<template>
	<div class="error-boundary">
		<div v-if="hasError" class="error-message">
			<h3>{{ $t('report.pageError') }}</h3>
			<p>{{ errorMessage }}</p>
			<button @click="reloadPage" class="reload-btn">{{ $t('report.reload') }}</button>
		</div>
		<div v-else-if="!infoData || !infoData.user" class="loading-message">
			<!-- <p>{{ $t('report.dataLoading') }}</p> -->

		</div>
		<div v-else class="report-bg" v-if="infoData && infoData.user">
			<div class="report-main" ref="reportMainRef" @mousedown="handleMouseDown" :class="{ 'dragging': isDragging }">
				<!-- 缩放时的滚动条指示器 -->
				<div v-if="tableScale > 1" class="scroll-indicator">
					<div class="scroll-indicator-text">可滚动查看</div>
				</div>
				<div class="report-content" :style="{ transform: `scale(${tableScale})`, transformOrigin: 'left top' }">
					<div v-if="showUnitName" class="unit-name">{{ unitName }}</div>
					<div class="report-title">{{ $t('report.title2') }}</div>
					<div class="block">
						<div class="block-title">{{ $t('report.personalInfo') }}</div>
						<div class="info-row">
							<div class="info-item fix-width"><span class="label">{{ $t('common.name') }}：</span><input class="input"
									:value="infoData.user.name" readonly /></div>
							<div class="info-item fix-width"><span class="label">{{ $t('common.age') }}：</span><input class="input"
									:value="infoData.user.age || '未知'" readonly />
							</div>
						</div>
						<div class="info-row u-f">
							<div class="info-item fix-width"><span class="label">{{ $t('common.gender') }}：</span>
								<span class="radio checked" v-if="infoData.user.sex == '0'">●{{ $t('common.male') }} </span>
								<span class="radio" v-else>○{{ $t('common.male') }}</span>

								<span class="radio checked" v-if="infoData.user.sex == '1'">●{{ $t('common.female') }} </span>
								<span class="radio" v-else>○{{ $t('common.female') }}</span>
							</div>
							<div class="info-item fix-width"><span class="label">{{ $t('common.id') }}：</span><input class="input id-input"
									:value="infoData.user.anamnesisid||infoData.user.id" readonly style="border: none !important; " /></div>
						</div>
					
					</div>
					<div class="block">
						<div class="block-title">{{ $t('report.assessmentInfo2') }}</div>
						<div class="info-row" v-if="infoData.gameName">
							<div class="info-item fix-width-100"><span class="label">{{ $t('report.assessmentScale') }}：</span>{{
								infoData.gameName }}</div>
						</div>
						
						<div class="info-row" v-if="trainingInfo && trainingInfo.length > 0">
							<div class="info-item fix-width" v-for="item in trainingInfo" :key="item.key">
								<span class="label" style="text-align: left;white-space: wrap;">{{ item.key }}：</span>{{ item.value }}
							</div>
						</div>
						<!-- 调试信息 -->
					
			
					</div>
			

					<div class="block" style="margin-top: 20px;"
						v-show="infoData.gameRecordDatas && infoData.gameRecordDatas.length">
						<div class="block-title">{{ $t('report.chartAnalysis') }} <span v-if="getChartTitle(0)"></span> </div>
						<div class="chart-area">
							<div 
								v-for="(record, index) in infoData.gameRecordDatas" 
								:key="index"
								:class="{ 'heatmap-container': getGameChartData(index).type === 'heatmap' }"
							>
								<div 
									class="chart-title"
									:class="{ 'heatmap-title': getGameChartData(index).type === 'heatmap' }"
								>
									{{ getGameChartData(index).seriesName }}
									<span 
										v-if="getChartDesc(index)" 
										style="color: #999; margin-left: 10px; font-size: 12px;"
									>
										{{ getChartDesc(index) }}
									</span>
								</div>
								<div 
									class="echart-box" 
									:class="{ 'heatmap': getGameChartData(index).type === 'heatmap' }"
									:ref="el => { if (el) chartRefs[index] = el as HTMLDivElement }"
								></div>
							</div>
						</div>
					</div>

					<!-- 统计信息 -->
					<div class="block" style="margin-top: 20px;" v-if="infoData.statistics">
						<div class="block-title">{{ getStatisticsTitle() }}</div>
						<div class="statistics-content">
							<!-- 列表类型 -->
							<div v-if="getStatisticsType() === 'list'" class="statistics-list">
								<div 
									v-for="(item, index) in getStatisticsData()" 
									:key="index" style="text-align: left;"
									class="statistics-item"
								>
									{{ item }}
								</div>
							</div>
							
							<!-- 表格类型 -->
							<div v-else-if="getStatisticsType() === 'table'" class="statistics-table-container">
								<table class="statistics-table">
									<thead>
										<tr>
											<th v-for="(header, index) in getTableHeaders()" :key="index">
												{{ header }}
											</th>
										</tr>
									</thead>
									<tbody>
										<tr v-for="(row, index) in getTableRows()" :key="index">
											<td v-for="(cell, cellIndex) in row" :key="cellIndex">
												{{ cell }}
											</td>
										</tr>
									</tbody>
								</table>
							</div>
						</div>
					</div>
					<div class="score" v-if="infoData.showTotalscore">
						<div class="u-f-ajsb " style="margin-bottom: 20px;">
							<div>{{ $t('report.totalScore') }}：</div>
							<div>{{ getTotalScore() }}{{ $t('common.score') }}</div>
						</div>
						<div style="color: #999;font-size: 15px;text-align: left;" v-html="infoData.scoreDesc"></div>
					</div>
					<div class="block">
						<div style="display: flex; gap: 10px; margin-bottom: 10px;">
							<button class="u-f-ac theme-btn-primary" style="margin-left: auto;height: 30px;
							border-radius: 50px;" @click="setDefault">{{ $t('report.preset') }}</button>
							<!-- <button class="u-f-ac" style="background-color: #4caf50;color: #fff;height: 30px;
							border-radius: 50px; padding: 0 15px;" @click="() => { console.log('用户手动点击生成热力图'); generateSmoothHeatmapData(true); }">生成平滑数据</button> -->
						</div>
						<div class="info-row align-top">
							<div class="info-item opinion-box">
								<span class="label">{{ $t('report.opinion') }}：</span>
								<textarea class="opinion-input" rows="2" v-model="assessAdvice" />
							</div>

						</div>
						<div class="info-item sign-box" style="margin-top: 30px;">
							<span class="label" style="margin-left: auto;">{{ $t('report.signature') }}：</span>
							<input class="signature-input" type="text"
								style="border: none;border-bottom: 2px solid #2176b8 !important;margin-right: 30px;padding-bottom: 8px;font-size: 16px;font-weight: 500;"
								v-model="therapistSignature" />
						</div>

					</div>
	
	
				</div>

			</div>
			<div class="right-btns">
				<button class="right-btn" @click="() => savePdf()">{{ $t('common.save') }}</button>
				<button class="right-btn" @click="printReport">{{ $t('common.print') }}</button>
				<button class="right-btn" @click="exitReport">{{ $t('common.exit') }}</button>
			</div>
			<div class="zoom-float-bar">
				<span class="zoom-label">{{ $t('report.zoom') }}：</span>
				<input type="range" min="0.5" max="2" step="0.01" v-model.number="tableScale" />
				<span class="zoom-value">{{ (tableScale * 100).toFixed(0) }}%</span>
			</div>
			<Dialog ref="orderRef" @close="closeEmpty" isClose>
				<div style="width: 50vw;">
					<div style="color: #000;font-size: 22px;margin-top: 20px;">{{ $t('report.preset') }}</div>
					<div class="def">
						<div class="def-input-row u-f-ac">
							<div class="def-input-col ">
								<div class="def-input-label" style="text-align: left;">{{ $t('settings.inputContent') }}</div>
								<textarea class="def-input-textarea" v-model="inputValue" maxlength="160" />
							</div>
							<button class="def-add-btn" @click="addRow">
								<svg width="28" height="28" viewBox="0 0 28 28">
									<circle cx="14" cy="14" r="14" fill="#2176b8" />
									<path d="M14 8v12M8 14h12" stroke="#fff" stroke-width="2" stroke-linecap="round" />
								</svg>
							</button>
						</div>
						<table class="def-table">
							<thead>
								<tr>
									<th
										style="width: 80px;border-right: 1px solid #fff;text-align: center;border-radius: 20px 0px 0px 0;">
										{{ $t('report.serialNumber') }}</th>
									<th style="border-right: 1px solid #fff;text-align: center;">{{ $t('settings.content') }}</th>
									<th style="width: 160px;text-align: center;border-radius: 0 20px 0px 0;">{{ $t('settings.operation')
									}}</th>
								</tr>
							</thead>
							<tbody>
								<tr v-for="(row, idx) in tableData" :key="row.id">
									<td class="def-td-serial">
										<div style="width: 120px;text-align: center;">{{ idx + 1 }}</div>
									</td>
									<!-- @click="startEdit(idx)" -->
									<td class="def-td-content">
										<div >{{ row.advice }}</div>
										<!-- <input v-else v-model="editingValue" class="edit-input" @blur="confirmEdit(idx)" /> -->
									</td>
									<td class="def-td-actions">
										<button @click="checkedRow(idx)" class="def-circle-btn checked" title="勾选">
											<i class="iconfont icon-duigou"></i>
										</button>
										<button @click="saveEdit(idx)" class="def-circle-btn edit" title="编辑">
											<i class="iconfont icon-xiugai"></i>
										</button>
										<button @click="deleteRow(idx)" class="def-circle-btn " title="删除">
											<i class="iconfont icon-shanchu"></i>
										</button>
									</td>
								</tr>
							</tbody>
						</table>
					</div>
				</div>
			</Dialog>
			<Message ref="messageRef" />
			<Dialog ref="dialogRef" >
      <div>
        <div style="color: #000;font-size: 22px;margin-top: 20px;">
        {{ $t('views.report.editTip') }}
      </div>
      <div class="dialog-btn" style="margin-top: 70px;">
        <button class="dialog-confirm" @click="eidtSave">{{ $t('common.confirm') }}</button>
        <button class="dialog-cancel" @click="closeDialog">{{ $t('common.cancel') }}</button>
      </div>
      </div>
    
    </Dialog>
		<Dialog ref="emptyRef" >
      <div>
        <div style="color: #000;font-size: 22px;margin-top: 20px;">
        {{ $t('views.report.editTipSave') }}
      </div>
      <div class="dialog-btn" style="margin-top: 70px;">
        <button class="dialog-confirm" @click="closeEdit">{{ $t('common.confirm') }}</button>
        <button class="dialog-cancel" @click="emptyRef.close()">{{ $t('common.cancel') }}</button>
      </div>
      </div>
    
    </Dialog>
		
		</div>
	</div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts';
import { ElLoading } from 'element-plus';
import html2canvas from 'html2canvas';
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import Dialog from '../../components/Dialog.vue';
import Message from '../../components/Message.vue';

// 定义组件名称，用于 keep-alive
defineOptions({
  name: 'tableGame'
});

declare global {
	interface Window {
		electron?: {
			ipcRenderer?: {
				invoke: (channel: string, ...args: any[]) => Promise<any>
			}
		}
	}
}
const emptyRef = ref<any>(null);
const route = useRoute()
const messageRef = ref<any>(null);
const dialogRef = ref<any>(null);
// 使用备用翻译系统
let t = (key: any) => key
let setLang = (newLang: any) => { }

// 创建响应式的翻译函数
const translationVersion = ref(0)
const $t = (key: any) => {
	// 依赖translationVersion来触发响应式更新
	translationVersion.value
	return t(key)
}
let tempIndex = -1
const eidtSave = () => {
	dialogRef.value.close()
	saveEdit(tempIndex)
	tempIndex = -1

}
const closeEdit = () => {
	console.log(1);
	
	emptyRef.value.close2()
	orderRef.value.close2()
}
const closeEmpty = () => {
	console.log(inputValue.value);
	
	if(inputValue.value){
		emptyRef.value.open()
	} else {
		inputValue.value=''
		
		orderRef.value.close2()
	}
}

// 初始化翻译函数
const initTranslations = async () => {
	try {
		const fallback = await import('../../utils/i18n-fallback')
		t = fallback.t
		setLang = (newLang: any) => {
			fallback.setLang(newLang)
			translationVersion.value++
		}
		// 监听语言变化事件
		window.addEventListener('language-changed', () => {
			translationVersion.value++
		})
	} catch (error) {
		console.warn('Failed to load i18n fallback:', error)
	}
}
const orderRef = ref<any>(null);
const router = useRouter();
const timeChartRef = ref<HTMLDivElement | null>(null);
const resultChartRef = ref<HTMLDivElement | null>(null);
const chartRefs = ref<(HTMLDivElement | null)[]>([]);
let timeChart: echarts.ECharts | null = null;
let resultChart: echarts.ECharts | null = null;
let charts: (echarts.ECharts | null)[] = [];

// 错误处理
const hasError = ref(false);
const errorMessage = ref('');

const resultData = [14, 5, 0];
const notSave = () => {
	orderRef.value.close()
}
const closeDialog = () => {
	dialogRef.value.close()
	tempIndex = -1
}
// 获取选中选项的分数显示（支持数值和字母等级）
const getSelectedScore = (options: any[]) => {
	if (!options || !options.length) return '';

	// 筛选真正选中的选项（必须有isSelected字段且为true）
	const selectedOptions = options.filter((o: any) => o.hasOwnProperty('isSelected') && o.isSelected === true);
	if (!selectedOptions.length) return '';

	// 如果只有一个选中项，直接返回其分数
	if (selectedOptions.length === 1) {
		const score = selectedOptions[0].score;
		// 对于数字类型（包括0），直接返回；其他情况检查是否有值
		if (typeof score === 'number') {
			return score.toString();
		}
		return score !== undefined && score !== null && score !== '' ? score : '';
	}

	// 多个选中项的情况
	const scores = selectedOptions.map((o: any) => o.score);

	// 检查是否都是数值（包括0）
	const allNumbers = scores.every((score: any) => {
		return typeof score === 'number' || (!isNaN(Number(score)) && score !== '' && score !== null && score !== undefined);
	});

	if (allNumbers) {
		// 如果都是数值，进行累加
		return scores.reduce((sum: number, score: any) => sum + Number(score), 0);
	} else {
		// 如果包含字母等级，用逗号连接（过滤掉空值）
		return scores.filter((score: any) => score !== '' && score !== null && score !== undefined).join(', ');
	}
}

// 计算一级大题总分（支持三级结构）
const getTypeScore = (type: any) => {
	if (!type.questionList || !type.questionList.length) {
		// 如果没有子题，显示大题本身的分数
		return getSelectedScore(type.options) || type.score || '';
	}

	// 有子题的情况，计算所有子题的数值分数总和
	let total = 0;
	let hasNumericScore = false;

	type.questionList.forEach((question: any) => {
		// 如果有第三级子题
		if (question.questionList && question.questionList.length > 0) {
			question.questionList.forEach((subQuestion: any) => {
				if (subQuestion.options && subQuestion.options.length > 0) {
					const selectedOptions = subQuestion.options.filter((option: any) => option.isSelected);
					selectedOptions.forEach((option: any) => {
						const score = Number(option.score);
						if (!isNaN(score)) {
							total += score;
							hasNumericScore = true;
						}
					});
				}
			});
		} else if (question.options && question.options.length > 0) {
			// 没有第三级子题的情况
			const selectedOptions = question.options.filter((option: any) => option.isSelected);
			selectedOptions.forEach((option: any) => {
				const score = Number(option.score);
				if (!isNaN(score)) {
					total += score;
					hasNumericScore = true;
				}
			});
		}
	});

	return hasNumericScore ? total : '';
}

// 计算二级题目总分（有第三级子题的情况）
const getSubTypeScore = (item: any) => {
	if (!item.questionList || !item.questionList.length) {
		return getSelectedScore(item.options) || item.score || '';
	}

	let total = 0;
	let hasNumericScore = false;

	item.questionList.forEach((subItem: any) => {
		if (subItem.options && subItem.options.length > 0) {
			const selectedOptions = subItem.options.filter((option: any) => option.isSelected);
			selectedOptions.forEach((option: any) => {
				const score = Number(option.score);
				if (!isNaN(score)) {
					total += score;
					hasNumericScore = true;
				}
			});
		}
	});

	return hasNumericScore ? total : '';
}

// 计算游戏图表数据
const getGameChartData = (recordIndex: number = 0) => {
	const defaultData = { xData: [], yData: [], seriesName: '', yAxisName: '', type: 'bar', data: [] };
	
	if (!infoData.value?.gameRecordDatas || !infoData.value.gameRecordDatas.length) {
		return defaultData;
	}

	// 取指定索引的游戏记录数据
	const record = infoData.value.gameRecordDatas[recordIndex];
	if (!record || !record.data) {
		return defaultData;
	}

			try {
			const parsedData = JSON.parse(record.data);
			console.log(parsedData);
			let unit = ''
			if (parsedData.unit) {
				unit = parsedData.unit
			}
			
			// 获取图表标题和x轴数据，支持中英文
			let chartTitle = parsedData.name
			let xAxisData = parsedData.xData || []
			const currentLang = localStorage.getItem('language') || 'zh-CN'
			console.log('Current language:', currentLang)
			console.log('Game data:', infoData.value?.game)
			console.log('reportCharField:', infoData.value?.game?.reportCharField)
			console.log('Parsed data:', parsedData)
			
			if (infoData.value?.game?.reportCharField) {
				try {
					const charFieldData = JSON.parse(infoData.value.game.reportCharField)
					console.log('Parsed charFieldData:', charFieldData)
					
					// 检查是否是对象还是数组
					if (charFieldData && typeof charFieldData === 'object') {
						let chartConfig: any = null
						
						if (Array.isArray(charFieldData)) {
							// 如果是数组，按索引选择
							if (charFieldData.length > 0) {
								chartConfig = charFieldData[recordIndex] || charFieldData[0]
							}
						} else {
							// 如果是对象，直接使用
							chartConfig = charFieldData
						}
						
						if (chartConfig) {
							console.log('Chart config for index', recordIndex, ':', chartConfig)
							
							if (chartConfig.charTitle) {
								chartTitle = chartConfig.charTitle
								console.log('Using English chart title:', chartTitle)
							}
							
							// 处理x轴数据映射
							if (chartConfig.horizontalAxis && parsedData.data) {
								// 按顺序循环对应，如果horizontalAxis不够就用空字符串补充
								xAxisData = parsedData.data.map((item: any, index: number) => {
									return chartConfig.horizontalAxis[index] || ''
								})
								
								console.log('Mapped xAxis data:', xAxisData)
							} else if (chartConfig.horizontalAxis) {
								xAxisData = chartConfig.horizontalAxis
								console.log('Using English xAxis data from config:', xAxisData)
							}
						}
					}
				} catch (error) {
					console.warn('解析英文图表配置失败:', error)
				}
			}
			
			console.log('Final chartTitle:', chartTitle)
			console.log('Final xAxisData:', xAxisData)
			
			// 检查是否为热力图数据
			if (parsedData.type === 'heatmap'||parsedData.type == '3'||record.dataType == 3||record.type == 3) {
				return {
					xData: xAxisData,
					yData: parsedData.yData || [],
					seriesName: chartTitle + unit,
					yAxisName: chartTitle || '',
					type: 'heatmap',
					data: parsedData.data || []
				};
			}
			
			// 检查是否为饼图数据
			if (parsedData.type === 2 || parsedData.type === '2'||record.type == 2||record.dataType == 2) {
				// 对于饼图，需要映射data中的name字段
				let pieData = parsedData.data || []
				if (infoData.value?.game?.reportCharField) {
					try {
						const charFieldData = JSON.parse(infoData.value.game.reportCharField)
						
						// 检查是否是对象还是数组
						if (charFieldData && typeof charFieldData === 'object') {
							let chartConfig: any = null
							
							if (Array.isArray(charFieldData)) {
								// 如果是数组，按索引选择
								if (charFieldData.length > 0) {
									chartConfig = charFieldData[recordIndex] || charFieldData[0]
								}
							} else {
								// 如果是对象，直接使用
								chartConfig = charFieldData
							}
							
							if (chartConfig && chartConfig.horizontalAxis) {
								// 按顺序映射data中的name
								pieData = pieData.map((item: any, index: number) => ({
									...item,
									name: chartConfig.horizontalAxis[index] || item.name
								}))
							}
						}
					} catch (error) {
						console.warn('解析英文饼图数据失败:', error)
					}
				}
				
				return {
					xData: xAxisData,
					yData: parsedData.yData || [],
					seriesName: chartTitle + unit,
					yAxisName: chartTitle || '',
					type: 'pie',
					data: pieData
				};
			}
			
			// 默认柱状图数据
			return {
				xData: xAxisData,
				yData: parsedData.yData || [],
				seriesName: chartTitle + unit,
				yAxisName: chartTitle || '',
				type: 'bar',
				data: parsedData.yData || []
			};
	} catch (error) {
		console.error('Failed to parse game record data:', error);
		return defaultData;
	}
}

// 计算图表数据
const getChartData = () => {
	if (!infoData.value?.questionTypeList) return { categories: [], scores: [] }
	console.log(infoData.value);

	// 判断是否为障碍类型分析
	// TODO 这里中英文要修改
	if (infoData.value.gameName === '功能独立性评定量表') {
		return getDisabilityTypeChartData()
	}
	
	// 判断是否为功能综合评定量表(FCA)
	if (infoData.value.gameName === '功能综合评定量表(FCA)') {
		return getFCAChartData()
	}
	const categories: string[] = []
	const scores: number[] = []

	infoData.value.questionTypeList.forEach((type: any) => {
		categories.push(type.questionType || type.title || '未知')

		let totalScore = 0
		if (type.questionList && type.questionList.length > 0) {
			type.questionList.forEach((question: any) => {
				// 如果有第三级子题
				if (question.questionList && question.questionList.length > 0) {
					question.questionList.forEach((subQuestion: any) => {
						if (subQuestion.options && subQuestion.options.length > 0) {
							// 只累加数值类型的分数
							const selectedOptions = subQuestion.options.filter((option: any) => option.isSelected)
							selectedOptions.forEach((option: any) => {
								const score = Number(option.score)
								if (!isNaN(score)) {
									totalScore += score
								}
							})
						}
					})
				} else if (question.options && question.options.length > 0) {
					// 没有第三级子题的情况
					const selectedOptions = question.options.filter((option: any) => option.isSelected)
					selectedOptions.forEach((option: any) => {
						const score = Number(option.score)
						if (!isNaN(score)) {
							totalScore += score
						}
					})
				}
			})
		} else if (type.options && type.options.length > 0) {
			// 处理大题本身有选项的情况
			const selectedOptions = type.options.filter((option: any) => option.isSelected)
			selectedOptions.forEach((option: any) => {
				const score = Number(option.score)
				if (!isNaN(score)) {
					totalScore += score
				}
			})
		}
		scores.push(totalScore)
	})

	return { categories, scores }
}

// 功能综合评定量表(FCA)的图表数据计算
const getFCAChartData = () => {
	const categories = [
		'自我照料',
		'括约肌控制',
		'转移',
		'行走',
		'言语理解',
		'言语表达',
		'社会交往（住院患者）',
		'社会交往（门诊或出院患者）',
		'问题解决能力',
		'记忆能力'
	]
	const scores = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

	// 遍历所有题目，根据题目标题精确分类
	infoData.value.questionTypeList.forEach((type: any) => {
		if (type.questionList && type.questionList.length > 0) {
			type.questionList.forEach((question: any) => {
				let categoryIndex = -1

				// 如果有第三级子题，遍历子题
				if (question.questionList && question.questionList.length > 0) {
					// 根据二级题目标题判断分类
					const title = question.title || ''
					
					if (title.includes('言语理解')) {
						categoryIndex = 4 // 言语理解
					} else if (title.includes('言语表达')) {
						categoryIndex = 5 // 言语表达
					} else if (title.includes('社会交往（住院患者）')) {
						categoryIndex = 6 // 社会交往（住院患者）
					} else if (title.includes('社会交往（门诊或出院患者）')) {
						categoryIndex = 7 // 社会交往（门诊或出院患者）
					} else if (title.includes('问题解决')) {
						categoryIndex = 8 // 问题解决能力
					} else if (title.includes('记忆')) {
						categoryIndex = 9 // 记忆能力
					}

					// 累加三级子题的分数
					if (categoryIndex !== -1) {
						question.questionList.forEach((subQuestion: any) => {
							if (subQuestion.options && subQuestion.options.length > 0) {
								const selectedOptions = subQuestion.options.filter((option: any) => option.hasOwnProperty('isSelected') && option.isSelected === true)
								selectedOptions.forEach((option: any) => {
									const score = Number(option.score)
									if (!isNaN(score)) {
										scores[categoryIndex] += score
									}
								})
							}
						})
					}
				} else {
					// 没有子题的情况，直接处理该题目
					const title = question.title || ''
					
					// 运动功能分类
					if (title.includes('自我照料')) {
						categoryIndex = 0 // 自我照料
					} else if (title.includes('括约肌控制') || title.includes('排尿') || title.includes('排便')) {
						categoryIndex = 1 // 括约肌控制
					} else if (title.includes('转移') || title.includes('床→椅') || title.includes('坐厕→轮椅') || title.includes('浴盆') || title.includes('淋浴')) {
						categoryIndex = 2 // 转移
					} else if (title.includes('行走') || title.includes('轮椅') || title.includes('楼梯')) {
						categoryIndex = 3 // 行走
					}

					// 累加该题目的分数
					if (categoryIndex !== -1 && question.options && question.options.length > 0) {
						const selectedOptions = question.options.filter((option: any) => option.hasOwnProperty('isSelected') && option.isSelected === true)
						selectedOptions.forEach((option: any) => {
							const score = Number(option.score)
							if (!isNaN(score)) {
								scores[categoryIndex] += score
							}
						})
					}
				}
			})
		}
	})

	// 保留一位小数
	const formattedScores = scores.map(score => Number(score.toFixed(1)))
	
	return { categories, scores: formattedScores }
}

// 障碍类型分析的图表数据计算
const getDisabilityTypeChartData = () => {
	const categories = [
		t('report.selfCare'),
		t('report.sphincterControl'),
		t('report.transfer'),
		t('report.walking'),
		t('report.communication'),
		t('report.socialCognition')
	]
	const scores = [0, 0, 0, 0, 0, 0]

	// 关键词映射
	const keywordMap: Record<string, number> = {
		'自理能力': 0,
		'进食': 0,
		'梳洗': 0,
		'洗澡': 0,
		'穿上衣': 0,
		'穿下衣': 0,
		'上厕所': 0,
		'括约肌': 1,
		'膀胱': 1,
		'直肠': 1,
		'转移': 2,
		'床': 2,
		'椅': 2,
		'轮椅': 2,
		'入厕': 2,
		'盆浴': 2,
		'淋浴': 2,
		'行走': 3,
		'步行': 3,
		'楼梯': 3,
		'交流': 4,
		'理解': 4,
		'表达': 4,
		'社会认知': 5,
		'社会交往': 5,
		'解决问题': 5,
		'记忆': 5
	}

	// 遍历所有题目，根据标题关键词分类累加分数
	infoData.value.questionTypeList.forEach((type: any) => {
		if (type.questionList && type.questionList.length > 0) {
			type.questionList.forEach((question: any) => {
				if (question.title && question.options && question.options.length > 0) {
					// 查找匹配的关键词
					let categoryIndex = -1
					for (const [keyword, index] of Object.entries(keywordMap)) {
						if (question.title.includes(keyword)) {
							categoryIndex = index
							break
						}
					}

					// 如果找到匹配的分类，累加选中选项的分数
					if (categoryIndex !== -1) {
						const selectedOptions = question.options.filter((option: any) => option.isSelected)
						selectedOptions.forEach((option: any) => {
							const score = Number(option.score)
							if (!isNaN(score)) {
								scores[categoryIndex] += score
							}
						})
					}
				}
			})
		}
	})

	return { categories, scores }
}

const tableScale = ref(1);
const hasShownZoomTip = ref(false);

// 监听缩放值变化，更新滚动条样式
watch(tableScale, (newScale) => {
	if (reportMainRef.value) {
		if (newScale > 1) {
			reportMainRef.value.classList.add('scaled');
			// 缩放后稍微滚动一下，确保滚动条可见
			setTimeout(() => {
				if (reportMainRef.value) {
					reportMainRef.value.scrollTop = 1;
					reportMainRef.value.scrollTop = 0;
				}
			}, 100);
			
			// 第一次缩放时显示提示
			if (!hasShownZoomTip.value) {
				hasShownZoomTip.value = true;
				if (messageRef.value) {
					messageRef.value.show('缩放后可以滚动查看完整内容', 'info');
				}
			}
		} else {
			reportMainRef.value.classList.remove('scaled');
		}
	}
});

const exitReport = async () => {
	try {
		// 先保存报告（不显示消息提示）
	} catch (error) {
		console.warn('退出时保存失败:', error)
	}

	// 然后退出页面
	if (route.query.id) {
		if (route.query.game == '1') {
			router.go(-2)

		} else { 
			router.back();

		}

	} else {
		await savePdf(false)
		router.go(-2)
	}
}
const setDefault = () => {
	orderRef.value.open();
}

const infoData = ref<any>({})
const trainingInfo = ref<any[]>([])

const inputValue = ref('')
const tableData = ref<any[]>([])
const editingIndex = ref<number>(-1)
const editingValue = ref('')

// 鼠标拖拽滚动相关
const isDragging = ref(false)
const startY = ref(0)
const startX = ref(0)
const startScrollTop = ref(0)
const startScrollLeft = ref(0)
const reportMainRef = ref<HTMLElement | null>(null)

// 音频播放相关
const currentPlaying = ref<string>('')
const isLoading = ref<Record<string, boolean>>({})
let currentAudio: HTMLAudioElement | null = null

const toggleAudio = (audioUrl: string, audioId: string) => {
	if (currentPlaying.value === audioId) {
		// 暂停当前播放
		if (currentAudio) {
			currentAudio.pause()
			currentAudio = null
		}
		currentPlaying.value = ''
	} else {
		// 停止之前的播放
		if (currentAudio) {
			currentAudio.pause()
			currentAudio = null
		}

		// 开始新的播放
		isLoading.value[audioId] = true
		currentAudio = new Audio(audioUrl)

		currentAudio.addEventListener('loadeddata', () => {
			isLoading.value[audioId] = false
			currentPlaying.value = audioId
		})

		currentAudio.addEventListener('ended', () => {
			currentPlaying.value = ''
			currentAudio = null
		})

		currentAudio.addEventListener('error', () => {
			isLoading.value[audioId] = false
			currentPlaying.value = ''
			currentAudio = null
			messageRef.value?.show(t('report.audioError'), 'error')
		})

		currentAudio.play().catch(() => {
			isLoading.value[audioId] = false
			currentPlaying.value = ''
			currentAudio = null
			messageRef.value?.show(t('report.audioError'), 'error')
		})
	}
}
const addRow = () => {
	if (!inputValue.value.trim()) {
		messageRef.value.show(t('messages.pleaseInput'), 'error')
		return
	}
	if (editingIndex.value != -1) {
		confirmEdit(editingIndex.value)
	} else { 
		window.request?.('/system/advice', {
		method: 'POST',
		body: {
			advice: inputValue.value.trim(),
		}
	}).then(res => {
		if (res?.data) {
			tableData.value.push(res.data)
		}
		getAdviceList()

		inputValue.value = ''
	})
	}
	
}
const deleteRow = (idx: number) => {
	const id = tableData.value[idx]?.id
	if (id) {
		window.request?.(`/system/advice/${id}`, { method: 'DELETE' }).then(() => {
			tableData.value.splice(idx, 1)
		})
		getAdviceList()

	}
}
const checkedRow = (idx: number) => {
	const val = tableData.value[idx]?.advice || ''
	assessAdvice.value = val
	orderRef.value.close2()
}
const startEdit = (idx: number) => {
	editingIndex.value = idx
	editingValue.value = tableData.value[idx]?.advice || ''
}
const cancelEdit = () => {
	editingIndex.value = -1
}
const confirmEdit = (idx: number) => {
	// const id = tableData.value[idx]?.id
	window.request?.(`/system/advice`, {
			method: 'PUT',
			body: {
				id: tableData.value[idx]?.id,
				advice: inputValue.value.trim()
			}
		}).then(res => {
			messageRef.value?.show(t('report.saveSuccess'), 'success')
			getAdviceList()
			if (res?.data) {
				tableData.value[idx] = res.data
			}
		})
	editingIndex.value = -1
}
const saveEdit = (idx: number) => {
	console.log(tempIndex);
	
	if (inputValue.value&&tempIndex==-1) {
		dialogRef.value.open()
		tempIndex = idx
		return
	 }
	editingIndex.value = idx
	inputValue.value = tableData.value[idx]?.advice || ''
}
const getAdviceList = () => {
	window.request?.('/system/advice/list', {
		method: 'GET', params: {
			pageSize: 9999,
		}
	}).then(res => {
		console.log(res);

		tableData.value = Array.isArray(res?.rows) ? res.rows : []
	})
}
const formatTime = (time: number | string, fmt: string = 'yyyy-MM-dd HH:mm:ss') => {
	let date: Date
	if (typeof time === 'string' && /^\d+$/.test(time)) {
		date = new Date(Number(time))
	} else if (typeof time === 'number') {
		date = new Date(time)
	} else {
		date = new Date(time as string)
	}
	const pad = (n: number) => n < 10 ? '0' + n : n.toString()
	const map: Record<string, string> = {
		'yyyy': date.getFullYear().toString(),
		'MM': pad(date.getMonth() + 1),
		'dd': pad(date.getDate()),
		'HH': pad(date.getHours()),
		'mm': pad(date.getMinutes()),
		'ss': pad(date.getSeconds()),
	}
	return fmt
		.replace('yyyy', map['yyyy'])
		.replace('MM', map['MM'])
		.replace('dd', map['dd'])
		.replace('HH', map['HH'])
		.replace('mm', map['mm'])
		.replace('ss', map['ss'])
}
const initCharts = () => {
	try {
		// 检查是否正在保存PDF，如果是则跳过
		const isSavingPdf = (globalThis as any).__savingPdf;
		if (isSavingPdf) {
			console.log('跳过 initCharts - 正在保存PDF');
			return;
		}
		
		// 检查是否有游戏记录数据
		const gameRecordData = infoData.value?.gameRecordDatas;
		if (!gameRecordData || !gameRecordData.length) {
			console.log('No game record data available');
			return;
		}

		// 销毁现有图表
		charts.forEach(chart => {
			if (chart) {
				try {
					chart.dispose();
				} catch (e) {
					console.warn('Error disposing previous chart:', e);
				}
			}
		});
		charts = [];

		// 为每个数据记录创建图表
		gameRecordData.forEach((record: any, index: number) => {
			const chartContainer = chartRefs.value[index];
			if (!chartContainer) return;

			try {
				const chart = echarts.init(chartContainer);
				if (!chart) {
					console.error(`Failed to create chart instance ${index}`);
					return;
				}

				// 解析游戏记录数据
				const chartData = getGameChartData(index);
				console.log(`Chart ${index} data:`, chartData);
				console.log(`Chart ${index} xData:`, chartData.xData);
				console.log(`Chart ${index} xData length:`, chartData.xData.length);
				console.log(`Chart ${index} data length:`, chartData.data.length);
				
				if (!chartData.xData.length && !chartData.data.length) {
					console.log(`No valid chart data found for chart ${index}`);
					return;
				}

				const dataLength = chartData.xData.length;

				// 根据图表类型设置不同的配置
				if (chartData.type === 'pie') {
					// 饼图配置
					chart.setOption({
						title: {
							left: 'center',
							top: 10,
							textStyle: {
								color: '#2176b8',
								fontSize: 16,
								fontWeight: 500
							}
						},
						tooltip: {
							trigger: 'item',
							backgroundColor: 'rgba(255, 255, 255, 0.95)',
							borderColor: '#2176b8',
							borderWidth: 1,
							textStyle: {
								color: '#333'
							},
							formatter: function (params: any) {
								const value = typeof params.value === 'number' ? params.value.toFixed(1) : params.value;
								const percent = typeof params.percent === 'number' ? params.percent.toFixed(1) : params.percent;
								const currentLang = localStorage.getItem('language') || 'zh-CN'
								const valueLabel = currentLang === 'en-US' ? 'Value' : '数值'
								const percentLabel = currentLang === 'en-US' ? 'Percentage' : '占比'
								return `${params.name}<br/>${valueLabel}: ${value}<br/>${percentLabel}: ${percent}%`;
							}
						},
				
						series: [{
							type: 'pie',
							radius: ['40%', '70%'],
							center: ['50%', '55%'],
							data: chartData.data,
							emphasis: {
								itemStyle: {
									shadowBlur: 10,
									shadowOffsetX: 0,
									shadowColor: 'rgba(0, 0, 0, 0.5)'
								}
							},
							label: {
								show: true,
								formatter: function (params: any) {
									const value = typeof params.value === 'number' ? params.value.toFixed(1) : params.value;
									const percent = typeof params.percent === 'number' ? params.percent.toFixed(1) : params.percent;
									return `${params.name}\n${value} (${percent}%)`;
								},
								fontSize: 11,
								color: '#333'
							},
							labelLine: {
								show: true
							},
							itemStyle: {
								color: function (params: any) {
									const colors = ['#2176b8', '#4caf50', '#ff9800', '#e91e63', '#9c27b0', '#00bcd4', '#ffeb3b', '#795548', '#607d8b', '#f44336'];
									return colors[params.dataIndex % colors.length];
								}
							}
						}]
					});
				} else if (chartData.type === 'heatmap') {
					// 检查是否允许渲染热力图
					const isSavingPdf = (globalThis as any).__savingPdf;
					if (isSavingPdf) {
						console.log(`跳过热力图 ${index} 渲染 - 正在保存PDF`);
						return;
					}
					
					// 计算数据的最小值和最大值
					const values = chartData.data.map((item: any) => item[2]);
					const minValue = 0;
					const maxValue = 7;
					
					// 计算数据范围
					const xMin = Math.min(...chartData.data.map((item: any) => item[0]));
					const xMax = Math.max(...chartData.data.map((item: any) => item[0]));
					const yMin = Math.min(...chartData.data.map((item: any) => item[1]));
					const yMax = Math.max(...chartData.data.map((item: any) => item[1]));
					
					// 计算中心线位置
					const centerX = (xMin + xMax) / 2;
					
					// 使用scatter类型的平滑热力图配置
					chart.setOption({
						backgroundColor: '#000',
						grid: {
							left: 0,
							right: 0,
							top: 0,
							bottom: 0
						},
						xAxis: {
							type: 'value',
							min: xMin,
							max: xMax,
							show: false
						},
						yAxis: {
							type: 'value',
							min: yMin,
							max: yMax,
							show: false
						},
						visualMap: {
							min: minValue,
							max: maxValue,
							show: false,
							inRange: {
								color: [
									'#000040',
									'#0000FF',
									'#0080FF',
									'#00FF80',
									'#80FF00',
									'#FFFF00',
									'#FF8000',
									'#FF4000',
									'#FF0000'
								]
							}
						},
						series: [{
							type: 'scatter',
							data: chartData.data,
							symbolSize: function(data: any) {
								// 根据数据值调整点大小，确保平滑覆盖
								const normalizedValue = (data[2] - minValue) / (maxValue - minValue);
								return Math.max(12, Math.min(25, normalizedValue * 20 + 12));
							},
							itemStyle: {
								opacity: 0.6
							},
							label: {
								show: false
							},
							animation: false
						}, {
							name: '中心线',
							type: 'line',
							data: [[centerX, yMin], [centerX, yMax]],
							symbol: 'none',
							lineStyle: {
								color: '#fff',
								width: 2,
								opacity: 0.9
							},
							animation: false
						}],
						tooltip: {
							position: 'top',
							backgroundColor: 'rgba(0, 0, 0, 0.8)',
							borderColor: '#fff',
							textStyle: {
								color: '#fff'
							},
							formatter: function (params: any) {
								if (!params || !params.data) return '';
								const data = params.data;
								const value = typeof data[2] === 'number' ? data[2].toFixed(1) : data[2];
								const currentLang = localStorage.getItem('language') || 'zh-CN'
								const coordLabel = currentLang === 'en-US' ? 'Coordinate' : '坐标'
								const intensityLabel = currentLang === 'en-US' ? 'Intensity' : '强度'
								return `${coordLabel}: (${Math.round(data[0])}, ${Math.round(data[1])})<br/>${intensityLabel}: ${value}`;
							}
						}
					});
				} else {
					// 柱状图配置
					console.log(`Setting chart ${index} xAxis data:`, chartData.xData);
					chart.setOption({
						title: {
							left: 'center',
							top: 10,
							textStyle: {
								color: '#2176b8',
								fontSize: 16,
								fontWeight: 500
							}
						},
						grid: {
							left: 50,
							right: 30,
							top: 50,
							bottom: dataLength > 20 ? 140 : dataLength > 15 ? 120 : dataLength > 10 ? 100 : dataLength > 5 ? 80 : 60
						},
						xAxis: {
							type: 'category',
							data: chartData.xData,
							axisLine: { lineStyle: { color: '#2176b8' } },
							axisLabel: {
								color: '#2176b8',
								fontWeight: 500,
								rotate: dataLength > 12 ? 45 : dataLength > 8 ? 30 : dataLength > 5 ? 15 : 0,
								interval: 0, // 显示所有标签
								fontSize: dataLength > 20 ? 8 : dataLength > 15 ? 9 : dataLength > 10 ? 10 : 11,
								margin: dataLength > 20 ? 15 : dataLength > 15 ? 12 : dataLength > 10 ? 10 : 8,
								formatter: function(value: string) {
									// 如果标签太长，进行截断
									if (value && value.length > 6) {
										return value.substring(0, 6) + '...';
									}
									return value;
								}
							},
							axisTick: {
								alignWithLabel: true
							}
						},
						yAxis: {
							type: 'value',
							name: '',
							nameTextStyle: { color: '#2176b8', fontWeight: 500, fontSize: 13 },
							axisLine: { lineStyle: { color: '#2176b8' } },
							axisLabel: { color: '#2176b8', fontWeight: 500 },
							splitLine: { lineStyle: { color: '#e0eaf3' } },
						},
						series: [{
							data: chartData.data,
							type: 'bar',
							name: chartData.seriesName || '',
							itemStyle: {
								color: function (params: any) {
									const colors = ['#2176b8', '#4caf50', '#ff9800', '#e91e63', '#9c27b0', '#00bcd4', '#ffeb3b', '#795548', '#607d8b', '#f44336'];
									return colors[params.dataIndex % colors.length];
								},
								borderRadius: dataLength > 15 ? [3, 3, 0, 0] : dataLength > 10 ? [4, 4, 0, 0] : [6, 6, 0, 0],
							},
							barWidth: Math.min(30, Math.max(8, 250 / Math.max(dataLength, 1))),
							label: {
								show: true,
								position: 'top',
								color: '#2176b8',
								fontSize: dataLength > 15 ? 11 : dataLength > 10 ? 12 : 13,
								fontWeight: 500,
								formatter: function (params: any) {
									return typeof params.value === 'number' ? params.value.toFixed(1) : params.value;
								}
							},
						}],
						tooltip: {
							trigger: 'axis',
							backgroundColor: 'rgba(255, 255, 255, 0.95)',
							borderColor: '#2176b8',
							borderWidth: 1,
							textStyle: {
								color: '#333'
							},
							formatter: function (params: any) {
								if (!params || !params[0]) return '';
								const data = params[0];
								const value = typeof data.value === 'number' ? data.value.toFixed(1) : data.value;
								return `${data.name}<br/>${chartData.seriesName || '数值'}: ${value}`;
							}
						}
					});
				}

				charts[index] = chart;
				console.log(`Chart ${index} initialized successfully`);
			} catch (chartError) {
				console.error(`Chart ${index} creation error:`, chartError);
				// 图表创建失败时不抛出错误，只是跳过图表
			}
		});

		// 简化第二个图表的初始化，如果有需要的话
		if (resultChartRef.value && resultData && resultData.length > 0) {
			try {
				if (resultChart) {
					resultChart.dispose();
					resultChart = null;
				}

				resultChart = echarts.init(resultChartRef.value);
				if (resultChart) {
					resultChart.setOption({
						grid: { left: 40, right: 20, top: 30, bottom: 30 },
						xAxis: {
							type: 'category',
							data: [t('report.correct'), t('report.incorrect'), t('report.hint')],
							axisLine: { lineStyle: { color: '#2176b8' } },
							axisLabel: { color: '#2176b8', fontWeight: 500 },
						},
						yAxis: {
							type: 'value',
							name: '',
							nameTextStyle: { color: '#2176b8', fontWeight: 500, fontSize: 13 },
							axisLine: { lineStyle: { color: '#2176b8' } },
							axisLabel: { color: '#2176b8', fontWeight: 500 },
							splitLine: { lineStyle: { color: '#e0eaf3' } },
						},
						series: [{
							data: resultData,
							type: 'bar',
							itemStyle: {
								color: function (params: any) {
									return ['#2176b8', '#4caf50', '#bdbdbd'][params.dataIndex];
								},
								borderRadius: [6, 6, 0, 0],
							},
							barWidth: 32,
							label: {
								show: true,
								position: 'top',
								color: '#2176b8',
								fontSize: 13,
								fontWeight: 500,
							},
						}],
					});
				}
			} catch (resultChartError) {
				console.error('Result chart creation error:', resultChartError);
			}
		}
	} catch (error) {
		console.error('Charts initialization error:', error);
		// 不要让图表错误影响整个页面
	}
}
let upData: any = null
const upLoadFile = async () => {
	try {
		if (!upData || !upData.questionTypeList) {
			console.log('No data to upload');
			return;
		}

		// 收集所有需要上传的文件
		const filesToUpload: Array<{
			data: string,
			type: 'canvas' | 'audio',
			path: string
		}> = [];

		// 安全地遍历questionTypeList
		if (Array.isArray(upData.questionTypeList)) {
			upData.questionTypeList.forEach((type: any, typeIdx: number) => {
				try {
					// 检查大题级别的audio
					if (type.audio && typeof type.audio === 'string') {
						filesToUpload.push({
							data: type.audio,
							type: 'audio',
							path: `questionTypeList[${typeIdx}].audio`
						});
					}

					// 检查子题
					if (type.questionList && Array.isArray(type.questionList)) {
						type.questionList.forEach((question: any, questionIdx: number) => {
							try {
								// 检查canvas
								if (question.canvas && typeof question.canvas === 'string') {
									filesToUpload.push({
										data: question.canvas,
										type: 'canvas',
										path: `questionTypeList[${typeIdx}].questionList[${questionIdx}].canvas`
									});
								}
								// 检查audio
								if (question.audio && typeof question.audio === 'string') {
									filesToUpload.push({
										data: question.audio,
										type: 'audio',
										path: `questionTypeList[${typeIdx}].questionList[${questionIdx}].audio`
									});
								}
							} catch (questionError) {
								console.warn(`Error processing question ${typeIdx}-${questionIdx}:`, questionError);
							}
						});
					}
				} catch (typeError) {
					console.warn(`Error processing type ${typeIdx}:`, typeError);
				}
			});
		}

		console.log(`Found ${filesToUpload.length} files to upload`);

		// 逐个上传文件
		for (const file of filesToUpload) {
			try {
				if (!window.request) {
					console.warn('Upload function not available');
					break;
				}

				let formData = new FormData();

				if (file.type === 'canvas') {
					// Canvas数据是base64格式，需要转换为Blob
					const base64Data = file.data.split(',')[1];
					if (!base64Data) continue;

					const byteCharacters = atob(base64Data);
					const byteNumbers = new Array(byteCharacters.length);
					for (let i = 0; i < byteCharacters.length; i++) {
						byteNumbers[i] = byteCharacters.charCodeAt(i);
					}
					const byteArray = new Uint8Array(byteNumbers);
					const blob = new Blob([byteArray], { type: 'image/png' });
					formData.append('file', blob, `canvas_${Date.now()}.png`);
				} else if (file.type === 'audio') {
					// Audio数据可能是blob URL
					if (file.data.startsWith('blob:')) {
						const response = await fetch(file.data);
						const blob = await response.blob();
						formData.append('file', blob, `audio_${Date.now()}.wav`);
					} else {
						console.warn('Unsupported audio format:', file.data);
						continue;
					}
				}

				// 上传文件
				const uploadResponse = await window.request('/common/upload', {
					method: 'POST',
					body: formData
				});

				if (uploadResponse && uploadResponse.url) {
					// 上传成功，更新数据中的URL
					const pathParts = file.path.split('.');
					let target = upData;

					// 导航到目标位置
					for (let i = 0; i < pathParts.length - 1; i++) {
						const part = pathParts[i];
						if (part.includes('[') && part.includes(']')) {
							const arrayName = part.split('[')[0];
							const index = parseInt(part.split('[')[1].split(']')[0]);
							if (target[arrayName] && target[arrayName][index]) {
								target = target[arrayName][index];
							} else {
								throw new Error(`Invalid path: ${file.path}`);
							}
						} else {
							if (target[part]) {
								target = target[part];
							} else {
								throw new Error(`Invalid path: ${file.path}`);
							}
						}
					}

					// 设置新的URL
					const finalKey = pathParts[pathParts.length - 1];
					target[finalKey] = uploadResponse.url;

					console.log(`Uploaded ${file.type} file: ${file.path} -> ${uploadResponse.url}`);
				}
			} catch (fileError) {
				console.error(`Error uploading file ${file.path}:`, fileError);
				// 继续处理其他文件
			}
		}

		// 更新infoData (但只在非保存PDF过程中)
		try {
			// 检查是否正在保存PDF，避免触发响应式更新导致图表重新生成
			const isSavingPdf = (globalThis as any).__savingPdf;
			if (!isSavingPdf) {
				infoData.value = { ...infoData.value, ...upData };
			}
			localStorage.setItem('infoData', JSON.stringify(infoData.value));
			console.log('File upload completed');
		} catch (updateError) {
			console.error('Error updating data after upload:', updateError);
		}

	} catch (error) {
		console.error('Error in upLoadFile:', error);
		// 不要让上传错误阻止页面渲染
	}
}

// 窗口大小变化处理函数
let handleResize: (() => void) | null = null

// 鼠标拖拽滚动事件处理
const handleMouseDown = (e: MouseEvent) => {
	// 如果点击的是按钮、输入框等交互元素，不启动拖拽
	const target = e.target as HTMLElement
	if (target.tagName === 'BUTTON' || target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' ||
		target.closest('button') || target.closest('input') || target.closest('textarea')) {
		return
	}

	if (!reportMainRef.value) return
	isDragging.value = true
	startY.value = e.clientY
	startX.value = e.clientX
	startScrollTop.value = reportMainRef.value.scrollTop
	startScrollLeft.value = reportMainRef.value.scrollLeft

	document.addEventListener('mousemove', handleMouseMove)
	document.addEventListener('mouseup', handleMouseUp)
	e.preventDefault()
}

const handleMouseMove = (e: MouseEvent) => {
	if (!isDragging.value || !reportMainRef.value) return
	const deltaY = e.clientY - startY.value
	const deltaX = e.clientX - startX.value
	reportMainRef.value.scrollTop = startScrollTop.value - deltaY
	reportMainRef.value.scrollLeft = startScrollLeft.value - deltaX
	e.preventDefault()
}

const handleMouseUp = () => {
	isDragging.value = false
	document.removeEventListener('mousemove', handleMouseMove)
	document.removeEventListener('mouseup', handleMouseUp)
}

const getData = async () => {

}

const showUnitName: any = ref(false)
const unitName: any = ref('')

onMounted(async () => {
	// 初始化翻译系统
	await initTranslations()
	
	// 检查初始缩放值，设置滚动条样式
	if (reportMainRef.value && tableScale.value > 1) {
		reportMainRef.value.classList.add('scaled');
	}
	
	// 监听主题变化事件
	window.addEventListener('theme-changed', handleThemeChange)
	
	// 只在首次挂载时允许热力图生成，后续禁止自动生成
	allowHeatmapGeneration = true
	setTimeout(() => {
		allowHeatmapGeneration = false
		console.log('禁用自动热力图生成，只允许用户手动触发')
		// 设置一个更严格的全局标志
		;(globalThis as any).__heatmapGenerationDisabled = true
	}, 3000) // 3秒后禁用自动生成

	//获取数据 不是新增
	if (route.query.id) {
		const loadingEl = ElLoading.service({
			lock: true,
			text: t('common.loading'),
			background: 'rgba(0, 0, 0, 0.7)',
		})
		
		try {
			addId = route.query.id as string
			let data: any = await window.request?.('/system/record/'+route.query.id, { method: 'GET', })
			console.log('API response data:', data);
			console.log('data.gameRecord:', data.gameRecord);
			console.log('data.gameRecord.game:', data.gameRecord?.game);
			console.log('data.game:', data.game);
			console.log('data.game keys:', Object.keys(data.game || {}));
			console.log('data.game.reportCharField:', data.game?.reportCharField);
			console.log('data keys:', Object.keys(data));
			assessAdvice.value = data.gameRecord.advice
			therapistSignature.value = data.gameRecord.signature
			try {
				console.log(data);
				
				infoData.value = data.gameRecord
				// 优先使用本地完整的用户数据，如果本地没有则使用API数据
				const localUserStr = localStorage.getItem('user')
				if (localUserStr) {
					try {
						const localUser = JSON.parse(localUserStr)
						// 合并本地用户数据和API用户数据，优先使用本地数据
						infoData.value.user = {
							...data.patient,
							...localUser,
							// 确保关键字段不被覆盖
							id: localUser.id || data.patient?.id,
							name: localUser.name || data.patient?.name,
							age: localUser.age || data.patient?.age,
							anamnesisid: localUser.anamnesisid || data.patient?.anamnesisid
						}
						console.log('Using merged user data:', infoData.value.user)
					} catch (parseError) {
						console.warn('Failed to parse local user data:', parseError)
						infoData.value.user = data.patient
					}
				} else {
					infoData.value.user = data.patient
				}
				// 添加游戏信息到infoData中
				if (data.game) {
					infoData.value.game = data.game
				}
				
				// 解析训练信息
				if (data.gameRecord.trainingInformation) {
					try {
						let trainingData = JSON.parse(data.gameRecord.trainingInformation)
						
						// 检查是否为英文环境
						const currentLang = localStorage.getItem('language') || 'zh-CN'
						console.log('Current language:', currentLang)
						console.log('Game data:', data.game)
						
						console.log('Training data before mapping:', trainingData)
						
						if (currentLang === 'en-US') {
							// 如果有game数据且有reportField，使用它来创建映射
							if (data.game && data.game.reportField) {
								try {
									const fieldMapping = JSON.parse(data.game.reportField)
									console.log('Field mapping from game data:', fieldMapping)
									
									// 创建中文key到英文key的映射
									const keyMapping: Record<string, string> = {}
									
									// 遍历trainingData，为每个中文key找到对应的英文key
									// 获取reportField中的所有英文key，按顺序循环映射
									const englishKeys = Object.keys(fieldMapping)
									console.log('English keys from reportField:', englishKeys)
									
									// 按照trainingData的顺序，依次使用英文key
									trainingData.forEach((item: any, index: number) => {
										if (index < englishKeys.length) {
											keyMapping[item.key] = englishKeys[index]
											console.log(`Mapping "${item.key}" -> "${englishKeys[index]}"`)
										}
									})
									
									console.log('Generated key mapping:', keyMapping)
									
									// 替换trainingData中的key
									trainingData = trainingData.map((item: any) => {
										const newKey = keyMapping[item.key]
										console.log(`Mapping key: "${item.key}" -> "${newKey}"`)
										const result = {
											...item,
											key: newKey || item.key
										}
										console.log('Result item:', result)
										return result
									})
									
									console.log('Training info translated to English:', trainingData)
								} catch (mappingError) {
									console.warn('Failed to parse reportField mapping:', mappingError)
									// 如果解析失败，使用硬编码映射作为备用
									const keyMapping: Record<string, string> = {
										'训练名称': 'trainingName',
										'训练时间': 'trainingDuration', 
										'开始时间': 'startTime',
										'分数': 'score'
									}
									
									trainingData = trainingData.map((item: any) => {
										const newKey = keyMapping[item.key]
										return {
											...item,
											key: newKey || item.key
										}
									})
								}
							} else {
								// 如果没有reportField，使用硬编码映射
								const keyMapping: Record<string, string> = {
									'训练名称': 'trainingName',
									'训练时间': 'trainingDuration', 
									'开始时间': 'startTime',
									'分数': 'score'
								}
								
								trainingData = trainingData.map((item: any) => {
									const newKey = keyMapping[item.key]
									return {
										...item,
										key: newKey || item.key
									}
								})
							}
						}
						
						trainingInfo.value = trainingData
					} catch (trainingError) {
						console.error('Failed to parse training information:', trainingError)
						trainingInfo.value = []
					}
				}
				
				console.log('JSON parse successful, infoData:', infoData.value);
				console.log('User data:', infoData.value.user);
				console.log('Training info:', trainingInfo.value);
			} catch (parseError) {
				console.error('JSON parse error:', parseError);
				console.error('Raw data:', data.content);
			}
		} catch (error) {
			console.error('加载数据失败:', error);
		} finally {
			loadingEl.close()
		}
	}
	try {
		// 安全地获取配置数据
		try {
			showUnitName.value = localStorage.getItem('showUnitName') === 'true';
			unitName.value = localStorage.getItem('unitName') || '';
		} catch (configError) {
			console.warn('Config loading error:', configError);
		}


		console.log(infoData.value);


		// 创建数据副本用于上传
		if (!route.query.id) {
			try {
				// 如果不是从query.id加载的数据，从localStorage获取
				const storedData = localStorage.getItem('infoData');
				if (storedData) {
					infoData.value = JSON.parse(storedData);
				}
				upData = JSON.parse(JSON.stringify(infoData.value));
			} catch (copyError) {
				console.warn('Data copy error:', copyError);
				upData = infoData.value; // 使用原始数据
			}
		}
		//结束任务
		if (localStorage.getItem('taskId')) {

			let user = JSON.parse(localStorage.getItem('user') || '{}')
			let taskId: any = localStorage.getItem('taskId')
			if (!taskId) {
				taskId = {
					id: ''
				}
			} else {
				taskId = JSON.parse(taskId)
			}
			let resource = localStorage.getItem('resource')
				let selconfigData=JSON.parse(localStorage.getItem('selconfigData')||'{}')
			//开始任务
			// window.request?.('/task/actionTask', {
			// 	method: 'POST', body: {
			// 		id: localStorage.getItem('scaleId'),
			// 		taskId: taskId.id,
			// 		executionNumber: taskId.executionNumber,
			// 		patientId: user.id,
			// 		resource: resource,
			// 		action: 3,
			// 		linkName:  selconfigData.game.name,
			// 		linkId: selconfigData.game.id,
			// 		type: 1
			// 	}
			// })

		}

		// 判断是否显示分数
		try {
			if (infoData.value.questionTypeList && Array.isArray(infoData.value.questionTypeList)) {
				infoData.value.questionTypeList.forEach((item: any) => {
					if (item.questionList && Array.isArray(item.questionList)) {
						item.questionList.forEach((question: any) => {
							if (question.options && Array.isArray(question.options)) {
								question.options.forEach((option: any) => {
									if (option.score && isNaN(option.score)) {
										showScore.value = false;
									}
								});
							}
						});
					}
				});
			}
		} catch (scoreError) {
			console.warn('Score checking error:', scoreError);
		}

		// 安全地上传文件
		try {
			await upLoadFile();
		} catch (uploadError) {
			console.warn('File upload error:', uploadError);
			// 继续执行，不让上传错误阻止页面渲染
		}

		// 获取评测预设列表
		try {
			getAdviceList();
		} catch (adviceError) {
			console.warn('Advice list error:', adviceError);
		}

		// 延迟初始化图表
		setTimeout(() => {
			try {
				initCharts();
			} catch (chartError) {
				console.warn('Chart initialization error:', chartError);
			}
		}, 200);

		// 添加页面可见性变化监听，防止切屏时重新生成热力图
		const handleVisibilityChange = () => {
			if (document.visibilityState === 'visible') {
				console.log('页面重新可见，但禁用热力图自动生成')
				// 不要在页面重新可见时自动生成热力图
			}
		}
		document.addEventListener('visibilitychange', handleVisibilityChange);

		// 将监听器保存到组件实例，以便清理
		;(globalThis as any).__visibilityHandler = handleVisibilityChange

		// 添加窗口大小变化监听
		handleResize = () => {
			try {
				// 避免在保存PDF过程中触发图表重新调整大小
				const isSavingPdf = (globalThis as any).__savingPdf;
				if (isSavingPdf) {
					console.log('Skipping chart resize during PDF save');
					return;
				}
				
				charts.forEach(chart => {
					if (chart) {
						chart.resize();
					}
				});
				if (resultChart) {
					resultChart.resize();
				}
			} catch (resizeError) {
				console.warn('Chart resize error:', resizeError);
			}
		}
		window.addEventListener('resize', handleResize);

	} catch (error) {
		handleError(error, '页面初始化');
	}

});

onBeforeUnmount(() => {
	// 移除窗口大小变化监听器
	if (handleResize) {
		window.removeEventListener('resize', handleResize)
		handleResize = null
	}
	
	// 移除页面可见性变化监听器
	const visibilityHandler = (globalThis as any).__visibilityHandler
	if (visibilityHandler) {
		document.removeEventListener('visibilitychange', visibilityHandler)
		;(globalThis as any).__visibilityHandler = null
	}
	
	// 移除主题变化监听器
	window.removeEventListener('theme-changed', handleThemeChange)

	// 销毁图表实例
	charts.forEach(chart => {
		if (chart) {
			chart.dispose();
		}
	});
	charts = [];
	if (timeChart) {
		timeChart.dispose();
		timeChart = null;
	}
	if (resultChart) {
		resultChart.dispose();
		resultChart = null;
	}
	// 清理音频资源
	if (currentAudio) {
		currentAudio.pause();
		currentAudio = null;
	}
});
let addId = ''
const assessAdvice = ref('')
const therapistSignature = ref('')
let isAdd = false

const addHisData = (imageBase64: string) => {
	let taskId: any = localStorage.getItem('taskId')
	// console.log();
	// 	let a = JSON.stringify(infoData.value)
	// 	let b = JSON.parse(a)
	// 	console.log(a);

	// 	console.log(b);

	if (!taskId) {
		taskId = {
			id: ''
		}
	} else {
		taskId = JSON.parse(taskId)
	}
	let obj: any = {
		image: imageBase64,
		scaleName: infoData.value.gameName,
		advice: assessAdvice.value,
		isTempSave: 1,
		patientId: infoData.value.user.id,
		scaleId: localStorage.getItem('scaleId'),
		signature: therapistSignature.value,
		total: getTotalScore(),
		taskId: taskId.id,
		executionNumber: taskId.executionNumber,
		// TODO 这里的任务还没传
		content: JSON.stringify(infoData.value),
		scoreDetail: JSON.stringify(infoData.value),
		patientName: infoData.value.user.name,
		startTime: formatTime(infoData.value.startTime, 'yyyy-MM-dd HH:mm:ss'),
		endTime: formatTime(infoData.value.endTime, 'yyyy-MM-dd HH:mm:ss'),
	}
	isAdd = true
	
	const loadingEl = ElLoading.service({
		lock: true,
		text: t('common.loading'),
		background: 'rgba(0, 0, 0, 0.7)',
	})
	
	//修改
	if (addId) {
		obj.id = addId
		window.request?.('/system/record', { method: 'PUT', body: obj }).then((res: any) => {
			console.log(res);
			if (res.id) {
				addId = res.id
			 }
			loadingEl.close()
		}).catch((error) => {
			console.error('保存失败:', error);
			loadingEl.close()
		})
	} else { 
		console.log(obj);
	//添加				
	window.request?.('/system/record', { method: 'POST', body: obj }).then((res: any) => {
		console.log(res);
		addId = res
		loadingEl.close()
	}).catch((error) => {
		console.error('保存失败:', error);
		loadingEl.close()
	})
	}
}
const savePdf = async (showMessage: boolean = true) => {
	//保存过，又退出的情况
	if (isAdd && !showMessage) { return }
	if (!reportMainRef.value) return;

	// 设置保存PDF标志，防止upLoadFile触发infoData更新导致图表重新生成
	(globalThis as any).__savingPdf = true;

	try {
		// 获取所有图表的图片数据
		const chartImageDataList: (string | null)[] = [];
		
		// 遍历所有图表实例
		if (charts && charts.length > 0) {
			for (let i = 0; i < charts.length; i++) {
				const chart = charts[i];
				if (chart) {
					try {
						// 不要在保存PDF时调用 resize，这可能触发热力图重新生成
						// chart.resize();
						await new Promise(resolve => setTimeout(resolve, 500));

						// 获取图表类型以确定背景色
						const gameChartData = getGameChartData(i);
						let backgroundColor = '#fff';
						
						if (gameChartData.type === 'heatmap') {
							backgroundColor = '#000'; // 热力图使用黑色背景
						}

						const imageData = chart.getDataURL({
							type: 'png',
							pixelRatio: 2,
							backgroundColor: backgroundColor
						});
						chartImageDataList[i] = imageData;
						console.log(`Chart ${i} image data obtained with background:`, backgroundColor);
					} catch (chartError) {
						console.error(`Failed to get chart ${i} image:`, chartError);
						chartImageDataList[i] = null;
					}
				} else {
					chartImageDataList[i] = null;
				}
			}
		}
		
		// 兼容旧的单个图表逻辑
		let chartImageData: string | null = null;
		if (timeChart && timeChartRef.value) {
			try {
				// 不要在保存PDF时调用 resize
				// timeChart.resize();
				await new Promise(resolve => setTimeout(resolve, 200));

				chartImageData = timeChart.getDataURL({
					type: 'png',
					pixelRatio: 2,
					backgroundColor: '#fff'
				});
				console.log('Time chart image data obtained');
			} catch (chartError) {
				console.error('Failed to get time chart image:', chartError);
			}
		}

		// 创建离屏容器
		const offscreenContainer = document.createElement('div');
		offscreenContainer.style.position = 'absolute';
		offscreenContainer.style.top = '-99999px';
		offscreenContainer.style.left = '-99999px';
		offscreenContainer.style.width = '800px'; // 固定宽度
		offscreenContainer.style.height = 'auto';
		offscreenContainer.style.overflow = 'visible';
		offscreenContainer.style.background = '#fff';
		offscreenContainer.style.zIndex = '-9999';
		offscreenContainer.style.pointerEvents = 'none';

		// 克隆报告内容
		const reportContent = reportMainRef.value.querySelector('.report-content') as HTMLElement;
		const clonedContent = reportContent.cloneNode(true) as HTMLElement;

		// 设置克隆内容的样式
		clonedContent.style.width = '800px';
		clonedContent.style.height = 'auto';
		clonedContent.style.overflow = 'visible';
		clonedContent.style.transform = 'none';
		clonedContent.style.transformOrigin = 'unset';

		// 将克隆内容添加到离屏容器
		offscreenContainer.appendChild(clonedContent);

		// 将离屏容器添加到body
		document.body.appendChild(offscreenContainer);

		// 等待DOM更新
		await new Promise(resolve => setTimeout(resolve, 100));

		// 处理所有图表 - 在克隆的内容中查找图表容器
		const clonedChartContainers = clonedContent.querySelectorAll('.echart-box') as NodeListOf<HTMLElement>;
		if (clonedChartContainers.length > 0) {
			for (let i = 0; i < clonedChartContainers.length; i++) {
				const container = clonedChartContainers[i];
				const imageData = chartImageDataList[i];
				
				if (imageData) {
					container.innerHTML = '';
					const chartImg = document.createElement('img');
					chartImg.src = imageData;
					chartImg.style.width = '100%';
					
					// 根据图表类型设置不同的高度
					const gameChartData = getGameChartData(i);
					if (gameChartData.type === 'heatmap') {
						chartImg.style.height = '200px';
						chartImg.style.backgroundColor = '#000'; // 热力图背景
					} else {
						chartImg.style.height = '300px';
						chartImg.style.backgroundColor = '#fff';
					}
					
					chartImg.style.objectFit = 'contain';
					chartImg.style.display = 'block';
					container.appendChild(chartImg);

					// 等待图片加载
					await new Promise(resolve => {
						chartImg.onload = resolve;
						chartImg.onerror = resolve;
						setTimeout(resolve, 800);
					});
					console.log(`Chart ${i} image added to cloned content`);
				}
			}
		}
		
		// 兼容旧的单个图表逻辑
		if (chartImageData && clonedChartContainers.length === 0) {
			const clonedChartContainer = clonedContent.querySelector('.echart-box') as HTMLElement;
			if (clonedChartContainer) {
				clonedChartContainer.innerHTML = '';
				const chartImg = document.createElement('img');
				chartImg.src = chartImageData;
				chartImg.style.width = '100%';
				chartImg.style.height = '300px';
				chartImg.style.objectFit = 'contain';
				chartImg.style.display = 'block';
				clonedChartContainer.appendChild(chartImg);

				await new Promise(resolve => {
					chartImg.onload = resolve;
					chartImg.onerror = resolve;
					setTimeout(resolve, 500);
				});
				console.log('Fallback chart image added to cloned content');
			}
		}

		// 再次等待确保所有内容都准备好
		await new Promise(resolve => setTimeout(resolve, 1000));

		// 获取实际尺寸
		const finalWidth = Math.max(clonedContent.scrollWidth, 800);
		const finalHeight = clonedContent.scrollHeight;

		console.log('Final dimensions:', { width: finalWidth, height: finalHeight });

		// 截图离屏内容
		const canvas = await html2canvas(clonedContent, {
			useCORS: true,
			allowTaint: true,
			scale: 2,
			scrollX: 0,
			scrollY: 0,
			width: finalWidth,
			height: finalHeight,
			backgroundColor: '#fff',
			logging: false
		});

		// 清理离屏容器
		document.body.removeChild(offscreenContainer);

		// 生成文件名
		const timestamp = formatTime(infoData.value.startTime, 'yyyyMMdd_HHmmss');
		const fileName = `${timestamp}.png`;
		const userFolderName = `${infoData.value.user.name}-${infoData.value.user.id}`;

		// 转换为blob并保存
		canvas.toBlob(async (blob: Blob | null) => {
			if (!blob) return;

			const arrayBuffer = await blob.arrayBuffer();
			await window.electron?.ipcRenderer?.invoke('save-image', fileName, arrayBuffer, userFolderName);
		}, 'image/png');


		addHisData(canvas.toDataURL('image/png'))
		if (window.messageRef?.show && showMessage) {
			window.messageRef.show(t('report.saveSuccess'), 'success');
		}
	} catch (error) {
		console.error('保存图片失败:', error);

		if (window.messageRef?.show) {
			window.messageRef.show(t('report.saveFailed'), 'error');
		}
	} finally {
		// 清除保存PDF标志
		(globalThis as any).__savingPdf = false;
	}
};

const showScore = ref(true)

// 检查是否有canvas数据
const hasCanvasData = computed(() => {
	if (!infoData.value?.questionTypeList) return false
	
	return infoData.value.questionTypeList.some((type: any) => {
		if (!type.questionList) return false
		
		return type.questionList.some((item: any) => {
			// 检查二级题目的canvas
			if (item.canvas) return true
			
			// 检查三级子题的canvas
			if (item.questionList && item.questionList.length > 0) {
				return item.questionList.some((subItem: any) => subItem.canvas)
			}
			
			return false
		})
	})
})
const printReport = async () => {
	try {
		// 滚动到顶部
		if (reportMainRef.value) {
			reportMainRef.value.scrollTop = 0;
		}

		// 检查是否在 Electron 环境中
		if (window.electron && window.electron.ipcRenderer) {
			// 使用 Electron 原生打印
			await printWithElectron();
		} else {
			// 使用浏览器打印
			await printWithBrowser();
		}
	} catch (error) {
		console.error('打印报告失败:', error);
		// 确保清理样式类
		document.body.classList.remove('pdf-exporting');

		// 显示错误信息
		if (messageRef.value) {
			messageRef.value.show(t('report.printFailed'), 'error');
		}
	}
};

// Electron 原生打印
const printWithElectron = async () => {
	try {
		// 添加打印样式
		document.body.classList.add('pdf-exporting');
		await new Promise(r => setTimeout(r, 300));

		let result;
		try {
			// 调用 Electron 主进程的打印功能
			result = await window.electron?.ipcRenderer?.invoke('print-report', {
				silent: false,
				printBackground: true,
				color: true,
				margins: {
					marginType: 'printableArea'
				},
				pageSize: 'A4',
				landscape: false
			});

			console.log('Electron 打印结果:', result);
		} catch (invokeError) {
			console.warn('Electron invoke 失败:', invokeError);
			// 如果 invoke 失败，降级到浏览器打印
			throw new Error('Electron 打印不可用，降级到浏览器打印');
		}

		// 检查结果是否有效
		if (!result) {
			console.warn('Electron 打印返回空结果，可能主进程未实现 print-report 处理程序');
			throw new Error('Electron 打印服务不可用');
		}

		if (result.success) {
			if (messageRef.value) {
				messageRef.value.show(t('report.printSuccess'), 'success');
			}
		} else {
			throw new Error(result.error || 'Electron print failed');
		}

	} catch (error: any) {
		console.log('Electron 打印失败，降级到浏览器打印:', error.message);
		document.body.classList.remove('pdf-exporting');
		// 降级到浏览器打印
		await printWithBrowser();
	} finally {
		document.body.classList.remove('pdf-exporting');
	}
};

// 浏览器打印
const printWithBrowser = async () => {
	try {
		// 添加打印样式类
		document.body.classList.add('pdf-exporting');

		// 等待样式应用和重新布局
		await new Promise(r => setTimeout(r, 800));

		// 直接使用当前窗口打印，避免弹窗问题
		try {
			window.print();

			// 显示成功消息
			setTimeout(() => {
				if (messageRef.value) {
					messageRef.value.show(t('report.printInitiated'), 'success');
				}
			}, 1000);

		} catch (printError) {
			console.error('直接打印失败:', printError);
			// 如果直接打印失败，尝试创建iframe方式
			await printWithIframe();
		}

	} finally {
		// 延迟移除样式类，确保打印对话框能正常显示
		setTimeout(() => {
			document.body.classList.remove('pdf-exporting');
		}, 1000);
	}
};

// 使用iframe打印（避免弹窗限制）
const printWithIframe = async () => {
	try {
		// 获取要打印的内容
		const reportContent = reportMainRef.value?.querySelector('.report-content');
		if (!reportContent) {
			throw new Error('找不到报告内容');
		}

		// 创建隐藏的iframe
		const iframe = document.createElement('iframe');
		iframe.style.position = 'absolute';
		iframe.style.top = '-9999px';
		iframe.style.left = '-9999px';
		iframe.style.width = '0px';
		iframe.style.height = '0px';
		iframe.style.border = 'none';

		document.body.appendChild(iframe);

		// 等待iframe加载
		await new Promise<void>((resolve) => {
			iframe.onload = () => resolve();

			// 构建打印页面HTML
			const printHTML = `
				<!DOCTYPE html>
				<html>
				<head>
					<meta charset="utf-8">
					<title>报告打印</title>
					<style>
						* { margin: 0; padding: 0; box-sizing: border-box; }
						body { 
							font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
							line-height: 1.4;
							color: #333;
							background: #fff;
							padding: 20px;
						}
						.print-container {
							max-width: 800px;
							margin: 0 auto;
						}
						.report-title {
							text-align: center;
							font-size: 22px;
							font-weight: bold;
							color: #2176b8 !important;
							margin-bottom: 20px;
							letter-spacing: 2px;
						}
						.unit-name {
							text-align: center;
							font-size: 18px;
							font-weight: bold;
							color: #2176b8 !important;
							margin-bottom: 10px;
						}
						.block {
							margin-bottom: 18px;
							page-break-inside: avoid;
						}
						.block-title {
							background: #2176b8 !important;
							color: #fff !important;
							font-size: 16px;
							font-weight: 500;
							padding: 8px 18px;
							margin-bottom: 10px;
						}
						.info-row {
							display: flex;
							flex-wrap: wrap;
							margin-bottom: 8px;
							padding: 0 18px;
						}
						.info-item {
							margin-right: 20px;
							margin-bottom: 5px;
						}
						.label {
							color: #2176b8 !important;
							font-weight: 500;
							margin-right: 5px;
						}
						.custom-table {
							width: 100%;
							border-collapse: collapse;
							margin: 10px 0;
							page-break-inside: auto;
						}
						.custom-table th,
						.custom-table td {
							border: 1px solid #000 !important;
							padding: 8px;
							text-align: left;
							font-size: 13px;
						}
						.custom-table th {
							background: #f5f8fa !important;
							font-weight: bold;
						}
						.opinion-input, .sign-input {
							border: 1px solid #ccc !important;
							padding: 5px;
							margin: 5px 0;
							min-height: 40px;
							display: block;
							width: 100%;
						}
						input[type="text"] {
							border: none !important;
							border-bottom: 1px solid #999 !important;
							background: transparent;
							outline: none;
						}
						@media print {
							body { 
								-webkit-print-color-adjust: exact !important;
								color-adjust: exact !important;
							}
							.block { page-break-inside: avoid; }
							.custom-table tr { page-break-inside: avoid; }
							.block-title {
								background: #2176b8 !important;
								color: #fff !important;
							}
						}
					</style>
				</head>
				<body>
					<div class="print-container">
						${reportContent.innerHTML}
					</div>
				</body>
				</html>
			`;

			iframe.src = 'data:text/html;charset=utf-8,' + encodeURIComponent(printHTML);
		});

		// 等待内容加载完成
		await new Promise(r => setTimeout(r, 500));

		// 尝试打印iframe内容
		try {
			if (iframe.contentWindow) {
				iframe.contentWindow.print();

				// 显示成功消息
				if (messageRef.value) {
					messageRef.value.show(t('report.printInitiated'), 'success');
				}
			}
		} catch (iframePrintError) {
			console.error('iframe打印失败:', iframePrintError);
			throw new Error('所有打印方式都失败了');
		}

		// 清理iframe（延迟移除，确保打印完成）
		setTimeout(() => {
			if (iframe.parentNode) {
				iframe.parentNode.removeChild(iframe);
			}
		}, 2000);

	} catch (error) {
		console.error('iframe打印方式失败:', error);
		throw error;
	}
};

// 计算总分（只计算数值类型的分数）
const getTotalScore = () => {
	if (!infoData.value?.questionTypeList) return '0.00'

	let total = 0
	infoData.value.questionTypeList.forEach((type: any) => {
		if (type.questionList && type.questionList.length > 0) {
			type.questionList.forEach((question: any) => {
				// 如果有第三级子题
				if (question.questionList && question.questionList.length > 0) {
					question.questionList.forEach((subQuestion: any) => {
						if (subQuestion.options && subQuestion.options.length > 0) {
							const selectedOptions = subQuestion.options.filter((option: any) => option.isSelected)
							selectedOptions.forEach((option: any) => {
								const score = Number(option.score)
								if (!isNaN(score)) {
									total += score
								}
							})
						}
					})
				} else if (question.options && question.options.length > 0) {
					// 没有第三级子题的情况
					const selectedOptions = question.options.filter((option: any) => option.isSelected)
					selectedOptions.forEach((option: any) => {
						const score = Number(option.score)
						if (!isNaN(score)) {
							total += score
						}
					})
				}
			})
		} else if (type.options && type.options.length > 0) {
			const selectedOptions = type.options.filter((option: any) => option.isSelected)
			selectedOptions.forEach((option: any) => {
				const score = Number(option.score)
				if (!isNaN(score)) {
					total += score
				}
			})
		}
	})
	console.log(total);

	return total
}

// 重新加载页面
const reloadPage = () => {
	window.location.reload();
}




// 获取统计信息标题
const getStatisticsTitle = () => {
	try {
		const currentLang = localStorage.getItem('language') || 'zh-CN'
		
		// 优先从reportCharField获取标题
		if (infoData.value?.game?.reportCharField) {
			try {
				const charFieldEn = JSON.parse(infoData.value.game.reportCharField)
				
				// 检查是否是对象还是数组
				if (charFieldEn && typeof charFieldEn === 'object') {
					if (Array.isArray(charFieldEn)) {
						// 如果是数组，取第一个配置
						if (charFieldEn.length > 0 && charFieldEn[0].title) {
							const title = charFieldEn[0].title
							// 如果是英文环境，翻译标题
							if (currentLang === 'en-US') {
								return translateTitle(title)
							}
							return title
						}
					} else {
						// 如果是对象，直接取title字段
						if (charFieldEn.title) {
							const title = charFieldEn.title
							// 如果是英文环境，翻译标题
							if (currentLang === 'en-US') {
								return translateTitle(title)
							}
							return title
						}
					}
				}
			} catch (error) {
				console.warn('解析reportCharField标题失败:', error)
			}
		}
		
		// 默认从statistics获取标题
		if (infoData.value?.statistics) {
			const statistics = typeof infoData.value.statistics === 'string' 
				? JSON.parse(infoData.value.statistics) 
				: infoData.value.statistics;
			const title = statistics.title || '统计信息';
			// 如果是英文环境，翻译标题
			if (currentLang === 'en-US') {
				return translateTitle(title)
			}
			return title;
		}
		return '统计信息';
	} catch (error) {
		console.warn('解析统计标题失败:', error);
		return '统计信息';
	}
}

// 获取统计信息类型
const getStatisticsType = () => {
	try {
		// 优先从reportCharField获取类型
		if (infoData.value?.game?.reportCharField) {
			try {
				const charFieldEn = JSON.parse(infoData.value.game.reportCharField)
				
				// 检查是否是对象还是数组
				if (charFieldEn && typeof charFieldEn === 'object') {
					if (Array.isArray(charFieldEn)) {
						// 如果是数组，取第一个配置
						if (charFieldEn.length > 0 && charFieldEn[0].type) {
							return charFieldEn[0].type
						}
					} else {
						// 如果是对象，直接取type字段
						if (charFieldEn.type) {
							return charFieldEn.type
						}
					}
				}
			} catch (error) {
				console.warn('解析reportCharField类型失败:', error)
			}
		}
		
		// 默认从statistics获取类型
		if (infoData.value?.statistics) {
			const statistics = typeof infoData.value.statistics === 'string' 
				? JSON.parse(infoData.value.statistics) 
				: infoData.value.statistics;
			return statistics.type || 'list';
		}
		return 'list';
	} catch (error) {
		console.warn('解析统计类型失败:', error);
		return 'list';
	}
}

// 翻译状态文字的函数
const translateStatusText = (text: string) => {
	const currentLang = localStorage.getItem('language') || 'zh-CN'
	
	if (currentLang === 'en-US') {
		// 状态文字翻译映射
		const statusMap: Record<string, string> = {
			'未出现': 'Not appeared',
			'全对': 'All correct',
			'全错': 'All wrong',
			'错1次': 'Wrong 1 time',
			'对1次': 'Correct 1 time',
			'错2次': 'Wrong 2 times',
			'对2次': 'Correct 2 times',
			'错3次': 'Wrong 3 times',
			'对3次': 'Correct 3 times',
			'错4次': 'Wrong 4 times',
			'对4次': 'Correct 4 times',
			'错5次': 'Wrong 5 times',
			'对5次': 'Correct 5 times',
			'错6次': 'Wrong 6 times',
			'对6次': 'Correct 6 times',
			'错7次': 'Wrong 7 times',
			'对7次': 'Correct 7 times',
			'错8次': 'Wrong 8 times',
			'对8次': 'Correct 8 times',
			'错9次': 'Wrong 9 times',
			'对9次': 'Correct 9 times',
			'错10次': 'Wrong 10 times',
			'对10次': 'Correct 10 times'
		}
		
		// 查找并替换状态文字
		for (const [chinese, english] of Object.entries(statusMap)) {
			if (text.includes(chinese)) {
				return text.replace(chinese, english)
			}
		}
	}
	
	return text
}

// 翻译表格数据的函数
const translateTableData = (data: any[]) => {
	const currentLang = localStorage.getItem('language') || 'zh-CN'
	
	if (currentLang === 'en-US') {
		// 颜色翻译映射
		const colorMap: Record<string, string> = {
			'黄色': 'Yellow',
			'绿色': 'Green',
			'蓝色': 'Blue',
			'红色': 'Red',
			'白色': 'White',
			'黑色': 'Black',
			'紫色': 'Purple',
			'橙色': 'Orange',
			'粉色': 'Pink',
			'灰色': 'Gray'
		}
		
		// 列名翻译映射
		const columnMap: Record<string, string> = {
			'颜色': 'Color',
			'精准(A)': 'Perfect Hits (A)',
			'一般(B)': 'Good Hits (B)',
			'错误(C)': 'Misses (C)',
			'命中率': 'Accuracy'
		}
		
		return data.map((row: any) => {
			const translatedRow: any = {}
			
			// 翻译每个字段
			for (const [key, value] of Object.entries(row)) {
				// 翻译列名
				const translatedKey = columnMap[key] || key
				
				// 翻译颜色值
				let translatedValue = value
				if (key === '颜色' || key === 'Color') {
					translatedValue = colorMap[value as string] || value
				}
				
				translatedRow[translatedKey] = translatedValue
			}
			
			return translatedRow
		})
	}
	
	return data
}

// 翻译标题的函数
const translateTitle = (title: string) => {
	const titleMap: Record<string, string> = {
		'分颜色统计': 'Color Specific Statistics',
		'统计信息': 'Statistics',
		'各符号答错次数统计': 'Symbol Error Statistics'
	}
	return titleMap[title] || title
}

// 合并表格数据的函数
const mergeTableData = (structureData: any[], actualData: any[]) => {
	console.log('=== mergeTableData 开始 ===')
	console.log('英文结构数据:', structureData)
	console.log('中文实际数据:', actualData)
	
	const currentLang = localStorage.getItem('language') || 'zh-CN'
	console.log('当前语言:', currentLang)
	
	if (currentLang === 'en-US') {
		// 按行顺序合并
		const result = structureData.map((structureRow: any, rowIndex: number) => {
			const actualRow = actualData[rowIndex]
			console.log(`\n=== 处理第${rowIndex}行 ===`)
			console.log('英文结构行:', structureRow)
			console.log('中文实际行:', actualRow)
			
			const mergedRow: any = {}
			
			// 获取英文结构的列名
			const englishKeys = Object.keys(structureRow)
			console.log('英文列名:', englishKeys)
			
			// 获取中文数据的列名
			const chineseKeys = actualRow ? Object.keys(actualRow) : []
			console.log('中文列名:', chineseKeys)
			
			// 按列顺序填充
			englishKeys.forEach((englishKey, colIndex) => {
				const chineseKey = chineseKeys[colIndex]
				const chineseValue = actualRow && chineseKey ? actualRow[chineseKey] : ''
				const englishValue = structureRow[englishKey]
				
				console.log(`第${colIndex}列: 英文键=${englishKey}, 中文键=${chineseKey}, 中文值=${chineseValue}, 英文默认值=${englishValue}`)
				
				// 完全按顺序替换：第0列用英文默认值，其他列用中文数据
				if (colIndex === 0) {
					// 第0列（颜色）使用英文默认值
					mergedRow[englishKey] = englishValue
					console.log(`第0列使用英文值: ${englishValue}`)
				} else {
					// 其他列使用中文数据
					mergedRow[englishKey] = chineseValue || englishValue
					console.log(`第${colIndex}列使用中文值: ${chineseValue || englishValue}`)
				}
			})
			
			console.log('合并后的行:', mergedRow)
			return mergedRow
		})
		
		console.log('\n=== 最终合并结果 ===')
		console.log(result)
		return result
	}
	
	// 如果是中文，直接返回实际数据
	return actualData
}

// 获取统计信息数据
const getStatisticsData = () => {
	try {
		console.log('=== getStatisticsData 开始 ===')
		
		// 获取中文统计数据
		let chineseData: any[] = []
		let statistics: any = null
		if (infoData.value?.statistics) {
			statistics = typeof infoData.value.statistics === 'string' 
				? JSON.parse(infoData.value.statistics) 
				: infoData.value.statistics;
			
			console.log('解析的statistics:', statistics)
			
			if (statistics.type === 'table' && Array.isArray(statistics.data)) {
				chineseData = statistics.data
				console.log('中文表格数据:', chineseData)
			} else if (statistics.type === 'list' && Array.isArray(statistics.data)) {
				console.log('中文列表数据:', statistics.data)
			}
		}
		
		// 优先从reportCharField获取表格结构
		if (infoData.value?.game?.reportCharField) {
			try {
				const charFieldEn = JSON.parse(infoData.value.game.reportCharField)
				
				// 检查是否是对象还是数组
				if (charFieldEn && typeof charFieldEn === 'object') {
					let config: any = null
					
					if (Array.isArray(charFieldEn)) {
						// 如果是数组，取第一个配置
						if (charFieldEn.length > 0) {
							config = charFieldEn[0]
						}
					} else {
						// 如果是对象，直接使用
						config = charFieldEn
					}
					
					if (config && config.type === 'table' && Array.isArray(config.data)) {
						console.log('reportCharField表格结构:', config.data)
						console.log('中文数据长度:', chineseData.length)
						
						// 如果有中文数据，将数据填充到结构中
						if (chineseData.length > 0) {
							console.log('开始调用mergeTableData')
							const mergedData = mergeTableData(config.data, chineseData)
							console.log('mergeTableData返回结果:', mergedData)
							return mergedData
						}
						// 如果没有中文数据，翻译表格结构
						console.log('没有中文数据，翻译表格结构')
						return translateTableData(config.data)
					} else if (config && config.type === 'list' && Array.isArray(config.data)) {
						// 如果是列表类型，翻译状态文字
						return config.data.map((item: string) => {
							// 检查是否是格式为 "【字母】:状态" 的字符串
							const match = item.match(/^【([A-Z])】:(.+)$/)
							if (match) {
								const letter = match[1]
								const status = match[2]
								const translatedStatus = translateStatusText(status)
								return `【${letter}】:${translatedStatus}`
							}
							
							// 如果不是特定格式，直接翻译整个字符串
							return translateStatusText(item)
						})
					}
				}
			} catch (error) {
				console.warn('解析reportCharField数据失败:', error)
			}
		}
		
		// 如果没有reportCharField，从statistics获取数据并翻译
		if (statistics) {
			console.log('没有reportCharField，处理statistics数据')
			console.log('statistics类型:', statistics.type)
			console.log('statistics数据:', statistics.data)
			
			if (statistics.type === 'list' && Array.isArray(statistics.data)) {
				// 如果是列表类型，翻译状态文字
				console.log('处理列表类型数据')
				const translatedList = statistics.data.map((item: string) => {
					console.log('处理列表项:', item)
					// 检查是否是格式为 "【字母】:状态" 的字符串
					const match = item.match(/^【([A-Z])】:(.+)$/)
					if (match) {
						const letter = match[1]
						const status = match[2]
						const translatedStatus = translateStatusText(status)
						const result = `【${letter}】:${translatedStatus}`
						console.log(`翻译: ${item} -> ${result}`)
						return result
					}
					
					// 如果不是特定格式，直接翻译整个字符串
					const result = translateStatusText(item)
					console.log(`翻译: ${item} -> ${result}`)
					return result
				})
				console.log('翻译后的列表数据:', translatedList)
				return translatedList
			} else if (statistics.type === 'table' && Array.isArray(statistics.data)) {
				// 如果是表格类型，翻译表格数据
				console.log('处理表格类型数据')
				const translatedData = translateTableData(statistics.data)
				console.log('翻译后的表格数据:', translatedData)
				return translatedData
			}
		}
		
		console.log('没有找到任何数据')
		return [];
	} catch (error) {
		console.warn('解析统计数据失败:', error);
		return [];
	}
}

// 获取表格表头
const getTableHeaders = () => {
	try {
		// 优先从reportCharField获取表头
		if (infoData.value?.game?.reportCharField) {
			try {
				const charFieldEn = JSON.parse(infoData.value.game.reportCharField)
				
				// 检查是否是对象还是数组
				if (charFieldEn && typeof charFieldEn === 'object') {
					let config: any = null
					
					if (Array.isArray(charFieldEn)) {
						// 如果是数组，取第一个配置
						if (charFieldEn.length > 0) {
							config = charFieldEn[0]
						}
					} else {
						// 如果是对象，直接使用
						config = charFieldEn
					}
					
					if (config && config.type === 'table' && Array.isArray(config.data) && config.data.length > 0) {
						// 从第一行数据中提取表头
						const firstRow = config.data[0];
						if (typeof firstRow === 'object' && firstRow !== null) {
							return Object.keys(firstRow);
						}
					}
				}
			} catch (error) {
				console.warn('解析reportCharField表头失败:', error)
			}
		}
		
		// 默认从statistics获取表头
		if (infoData.value?.statistics) {
			const statistics = typeof infoData.value.statistics === 'string' 
				? JSON.parse(infoData.value.statistics) 
				: infoData.value.statistics;
			
			if (statistics.type === 'table' && Array.isArray(statistics.data) && statistics.data.length > 0) {
				// 从第一行数据中提取表头
				const firstRow = statistics.data[0];
				if (typeof firstRow === 'object' && firstRow !== null) {
					return Object.keys(firstRow);
				}
			}
		}
		return [];
	} catch (error) {
		console.warn('解析表格表头失败:', error);
		return [];
	}
}

// 获取图表描述
const getChartDesc = (recordIndex: number = 0) => {
	try {
		if (!infoData.value?.gameRecordDatas || !infoData.value.gameRecordDatas.length) {
			return ''
		}

		const record = infoData.value.gameRecordDatas[recordIndex]
		if (!record || !record.data) {
			return ''
		}

		const parsedData = JSON.parse(record.data)
		const currentLang = localStorage.getItem('language') || 'zh-CN'
		
		// 如果有游戏数据配置
		if (infoData.value?.game?.reportCharField) {
			try {
				const charFieldData = JSON.parse(infoData.value.game.reportCharField)
				
				// 检查是否是对象还是数组
				if (charFieldData && typeof charFieldData === 'object') {
					let chartConfig: any = null
					
					if (Array.isArray(charFieldData)) {
						// 如果是数组，按索引选择
						if (charFieldData.length > 0) {
							chartConfig = charFieldData[recordIndex] || charFieldData[0]
						}
					} else {
						// 如果是对象，直接使用
						chartConfig = charFieldData
					}
					
					if (chartConfig && chartConfig.desc) {
						return chartConfig.desc
					}
				}
			} catch (error) {
				console.warn('解析英文图表描述失败:', error)
			}
		}
		
		// 默认返回原始描述
		return parsedData.desc || ''
	} catch (error) {
		console.warn('获取图表描述失败:', error)
		return ''
	}
}

// 获取图表标题
const getChartTitle = (chartIndex: number = 0) => {
	try {
		const currentLang = localStorage.getItem('language') || 'zh-CN'
		console.log('getChartTitle called - language:', currentLang, 'chartIndex:', chartIndex)
		console.log('getChartTitle - infoData.value.game:', infoData.value?.game)
		console.log('getChartTitle - reportCharField:', infoData.value?.game?.reportCharField)
		
		// 如果是英文环境且有游戏数据
		console.log('getChartTitle - Current language:', currentLang)
		console.log('getChartTitle - Has game data:', !!infoData.value?.game)
		console.log('getChartTitle - Has reportCharField:', !!infoData.value?.game?.reportCharField)
		
		// 临时调试：如果有reportCharField数据，强制使用英文逻辑
		if (infoData.value?.game?.reportCharField) {
			console.log('getChartTitle - Found reportCharField data, trying to parse')
			try {
				const charFieldEn = JSON.parse(infoData.value.game.reportCharField)
				console.log('getChartTitle - Parsed charFieldEn:', charFieldEn)
				
				// 检查是否是对象还是数组
				if (charFieldEn && typeof charFieldEn === 'object') {
					if (Array.isArray(charFieldEn)) {
						// 如果是数组，按索引选择
						if (charFieldEn.length > 0) {
							const chartConfig = charFieldEn[chartIndex] || charFieldEn[0]
							if (chartConfig && chartConfig.charTitle) {
								console.log('getChartTitle - Returning English title from array:', chartConfig.charTitle)
								return chartConfig.charTitle
							}
						}
					} else {
						// 如果是对象，直接取title字段
						if (charFieldEn.title) {
							console.log('getChartTitle - Returning English title from object:', charFieldEn.title)
							return charFieldEn.title
						}
					}
				}
			} catch (error) {
				console.warn('解析英文图表标题失败:', error)
			}
		}
		
		if (infoData.value?.game?.reportCharField) {
			console.log('getChartTitle - Found reportCharField data')
			try {
				const charFieldData = JSON.parse(infoData.value.game.reportCharField)
				console.log('getChartTitle - Parsed charFieldData:', charFieldData)
				
				// 检查是否是对象还是数组
				if (charFieldData && typeof charFieldData === 'object') {
					if (Array.isArray(charFieldData)) {
						// 如果是数组，按索引选择
						if (charFieldData.length > 0) {
							const chartConfig = charFieldData[chartIndex] || charFieldData[0]
							if (chartConfig && chartConfig.charTitle) {
								console.log('getChartTitle - Returning title from array:', chartConfig.charTitle)
								return chartConfig.charTitle
							}
						}
					} else {
						// 如果是对象，直接取title字段
						if (charFieldData.title) {
							console.log('getChartTitle - Returning title from object:', charFieldData.title)
							return charFieldData.title
						}
					}
				}
			} catch (error) {
				console.warn('解析图表标题失败:', error)
			}
		}
		
		// 默认返回原始标题
		const defaultTitle = infoData.value?.charTitle || ''
		console.log('getChartTitle - Returning default title:', defaultTitle)
		return defaultTitle
	} catch (error) {
		console.warn('获取图表标题失败:', error)
		return infoData.value?.charTitle || ''
	}
}

// 获取表格行数据
const getTableRows = () => {
	try {
		console.log('=== getTableRows 开始 ===')
		
		// 使用getStatisticsData获取处理后的数据
		const processedData = getStatisticsData()
		console.log('getStatisticsData返回的数据:', processedData)
		
		if (Array.isArray(processedData) && processedData.length > 0) {
			const rows = processedData.map((row: any) => {
				if (typeof row === 'object' && row !== null) {
					const values = Object.values(row)
					console.log('行数据:', values)
					return values;
				}
				return [];
			});
			console.log('最终表格行数据:', rows)
			return rows;
		}
		
		console.log('没有找到处理后的数据')
		return [];
	} catch (error) {
		console.warn('解析表格行数据失败:', error);
		return [];
	}
}

// 全局标志，防止非用户操作触发的热力图重新生成
let allowHeatmapGeneration = false

// 生成平滑热力图数据
const generateSmoothHeatmapData = (forceGenerate = false) => {
	// 如果不是强制生成且不允许生成，则跳过
	if (!forceGenerate && (!allowHeatmapGeneration || (globalThis as any).__heatmapGenerationDisabled)) {
		console.log('热力图生成被阻止，非用户操作 - allowGeneration:', allowHeatmapGeneration, 'disabled:', (globalThis as any).__heatmapGenerationDisabled)
		return
	}
	
	// 检查是否已经有热力图数据，避免重复生成
	const currentHeatmapIndex = infoData.value.gameRecordDatas?.findIndex((record: any) => {
		if (record.data) {
			try {
				const parsedData = JSON.parse(record.data)
				return parsedData.type === 'heatmap' || record.dataType === 3 || record.type === 3
			} catch {
				return false
			}
		}
		return false
	})
	
	if (currentHeatmapIndex !== -1 && !forceGenerate) {
		console.log('热力图数据已存在，跳过重新生成')
		return
	}
	
	const data = []
	const width = 300
	const height = 200
	
	// 增加数据点密度，使用更小的采样间隔
	for (let i = 0; i < width; i += 2) {
		for (let j = 0; j < height; j += 2) {
			// 使用多个高斯函数叠加创建平滑效果
			const x = (i - width/2) / 80
			const y = (j - height/2) / 80
			
			// 多个高斯函数叠加，模拟图片中的热点
			const value1 = 6 * Math.exp(-((x-1.2)**2 + (y-0.2)**2) / 0.8)  // 右上大热点
			const value2 = 5 * Math.exp(-((x+1.5)**2 + (y-0.6)**2) / 0.6)  // 左上小热点
			const value3 = 4.5 * Math.exp(-((x+1.2)**2 + (y+0.6)**2) / 0.7) // 左下小热点
			const value4 = 3 * Math.exp(-((x+0.2)**2 + (y)**2) / 1.2)      // 中间连接
			const value5 = 3.5 * Math.exp(-((x+0.8)**2 + (y+0.1)**2) / 0.5) // 右下小热点
			
			const totalValue = value1 + value2 + value3 + value4 + value5
			
			// 添加微小的随机噪声
			const noise = (Math.random() - 0.5) * 0.3
			const finalValue = Math.max(0, Math.min(7, totalValue + noise))
			
			// 保留所有数据点，包括低值点，以确保平滑覆盖
			if (finalValue > 0.1) {
				data.push([i, j, finalValue])
			}
		}
	}
	
	// 创建热力图数据对象
	const heatmapData = {
		type: "heatmap",
		name: "",
		xData: Array.from({length: width}, (_, i) => i),
		yData: Array.from({length: height}, (_, i) => i),
		data: data
	}
	
	// 创建gameRecordData对象
	const newGameRecord = {
		data: JSON.stringify(heatmapData),
		dataType: 3,
		type: 3
	}
	
	// 添加到infoData中
	if (!infoData.value.gameRecordDatas) {
		infoData.value.gameRecordDatas = []
	}
	
	// 检查是否已经有热力图数据，如果有就替换，没有就添加
	const existingHeatmapIndex = infoData.value.gameRecordDatas.findIndex((record: any) => {
		if (record.data) {
			try {
				const parsedData = JSON.parse(record.data)
				return parsedData.type === 'heatmap' || record.dataType === 3 || record.type === 3
			} catch {
				return false
			}
		}
		return false
	})
	
	if (existingHeatmapIndex !== -1) {
		// 替换现有的热力图数据
		infoData.value.gameRecordDatas[existingHeatmapIndex] = newGameRecord
	} else {
		// 添加新的热力图数据
		infoData.value.gameRecordDatas.push(newGameRecord)
	}
	
	// 重新初始化图表（只在不是保存PDF过程中且允许生成时才重新初始化）
	setTimeout(() => {
		const isSavingPdf = (globalThis as any).__savingPdf;
		if (!isSavingPdf && allowHeatmapGeneration) {
			console.log('自动调用 initCharts')
			initCharts()
		} else {
			console.log('跳过 initCharts 调用 - savingPdf:', isSavingPdf, 'allowGeneration:', allowHeatmapGeneration)
		}
	}, 100)
	
	// 显示成功消息
	if (messageRef.value) {
		messageRef.value.show('平滑热力图数据生成成功！', 'success')
	}
	
	console.log(`生成的数据点数量: ${data.length}`)
	console.log(`图表尺寸: ${width}x${height}`)
}

// 处理主题变化
const handleThemeChange = (event: any) => {
	console.log('报告页面接收到主题变化:', event.detail)
	// 这里可以添加特定的主题变化处理逻辑
}

// 安全的错误处理函数
const handleError = (error: any, context: string) => {
	console.error(`Error in ${context}:`, error);
	hasError.value = true;
	errorMessage.value = `${context}${t('report.dataInitError')}: ${error.message || t('errors.internalError')}`;
}


</script>

<style>
.iconfont {
	font-size: 25px;
}

body.pdf-exporting .right-btns,
body.pdf-exporting .zoom-float-bar,
body.pdf-exporting .report-bg::before,
body.pdf-exporting .report-bg::after {
	display: none !important;
}

.score {
	margin: 30px;
}

body.pdf-exporting .report-bg {
	background: #fff !important;
	height: auto !important;
	min-height: auto !important;
	overflow: visible !important;
}

body.pdf-exporting .report-main {
	box-shadow: none !important;
	margin: 0 auto !important;
	display: block !important;
	visibility: visible !important;
	opacity: 1 !important;
	height: auto !important;
	min-height: auto !important;
	overflow: visible !important;
	max-height: none !important;
}

body.pdf-exporting .report-content {
	height: auto !important;
	overflow: visible !important;
}

/* 确保打印时所有内容都显示 */
@media print {

	.right-btns,
	.zoom-float-bar {
		display: none !important;
	}

	.report-bg {
		background: #fff !important;
		height: auto !important;
		min-height: auto !important;
		overflow: visible !important;
		-webkit-print-color-adjust: exact !important;
		color-adjust: exact !important;
	}

	.report-main {
		box-shadow: none !important;
		margin: 0 auto !important;
		display: block !important;
		visibility: visible !important;
		opacity: 1 !important;
		height: auto !important;
		min-height: auto !important;
		overflow: visible !important;
		max-height: none !important;
		page-break-inside: avoid;
	}

	.report-content {
		height: auto !important;
		overflow: visible !important;
		page-break-inside: avoid;
	}

	.block {
		page-break-inside: avoid;
		break-inside: avoid;
	}

	.custom-table {
		page-break-inside: auto;
	}

	.custom-table tr {
		page-break-inside: avoid;
		break-inside: avoid;
	}
}

.canvas-name {
	font-size: 12px;
	color: #333;
	font-weight: 500;
}

.statistics-content {
	padding: 12px 18px;
}

.statistics-list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: 8px 20px;
	overflow-y: auto;
}

.statistics-item {
	font-size: 14px;
	color: #333;
	padding: 6px 12px;
	background: #f8f9fa;
	border-radius: 4px;
	line-height: 1.4;
	word-break: break-all;
}



/* 滚动条样式 */
.statistics-list::-webkit-scrollbar {
	width: 6px;
}

.statistics-list::-webkit-scrollbar-track {
	background: #f1f1f1;
	border-radius: 3px;
}

.statistics-list::-webkit-scrollbar-thumb {
	background: var(--theme-primary);
	border-radius: 3px;
}

.statistics-list::-webkit-scrollbar-thumb:hover {
	background: #158ac0;
}

/* 表格样式 */
.statistics-table-container {
	overflow-x: auto;
	margin: 0;
}

.statistics-table {
	width: 100%;
	border-collapse: collapse;
	font-size: 14px;
	background: #fff;
	border-radius: 6px;
	overflow: hidden;
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.statistics-table th {
	background: #2176b8;
	color: #fff;
	font-weight: 500;
	padding: 12px 16px;
	text-align: center;
	border: none;
	font-size: 14px;
}

.statistics-table th:first-child {
	text-align: left;
}

.statistics-table td {
	padding: 10px 16px;
	border-bottom: 1px solid #e8e8e8;
	text-align: center;
	color: #333;
	line-height: 1.4;
}

.statistics-table td:first-child {
	text-align: left;
	font-weight: 500;
	color: #2176b8;
}

.statistics-table tbody tr:hover {
	background-color: #f8f9fa;
}

.statistics-table tbody tr:last-child td {
	border-bottom: none;
}

/* 表格响应式 */
.statistics-table-container::-webkit-scrollbar {
	height: 6px;
}

.statistics-table-container::-webkit-scrollbar-track {
	background: #f1f1f1;
	border-radius: 3px;
}

.statistics-table-container::-webkit-scrollbar-thumb {
	background: #2176b8;
	border-radius: 3px;
}

.statistics-table-container::-webkit-scrollbar-thumb:hover {
	background: #158ac0;
}

.error-boundary {
	width: 100vw;
	min-height: 100vh;
	background: #f5f5f5;
}

.error-message {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	height: 100vh;
	text-align: center;
	color: #e74c3c;
}

.error-message h3 {
	font-size: 24px;
	margin-bottom: 16px;
}

.error-message p {
	font-size: 16px;
	margin-bottom: 24px;
	color: #666;
}

.reload-btn {
	background: #2176b8;
	color: #fff;
	border: none;
	border-radius: 8px;
	padding: 12px 24px;
	font-size: 16px;
	cursor: pointer;
	transition: background 0.2s;
}

.reload-btn:hover {
	background: #158ac0;
}

.loading-message {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 100vh;
	font-size: 18px;
	color: #2176b8;
}

.unit-name {
	text-align: center;
	font-size: 18px;
	font-weight: bold;
	color: #2176b8;
	margin-bottom: 10px;
}
</style>

<style scoped>
.report-bg {
	width: 100vw;
	min-height: 100vh;
	background: #000;
	display: flex;
	justify-content: center;
	align-items: flex-start;
	position: relative;
	overflow-x: hidden;
}

.report-main {
	width: 800px;
	background: #fff;
	margin: 0px 0 0px 0;
	border-radius: 2px;
	border: 1.5px solid #b5d2e8;
	box-sizing: border-box;
	padding: 20px 0 24px 0;
	height: 100vh;
	overflow: auto;
	cursor: grab;
	user-select: none;
	/* 确保滚动条始终可见 */
	overflow-x: auto;
	overflow-y: auto;
	/* 强制显示滚动条 */
	scrollbar-width: auto;
	-ms-overflow-style: auto;
}

.report-main:active,
.report-main.dragging {
	cursor: grabbing;
}

.report-main::-webkit-scrollbar {
	width: 12px;
	height: 12px;
	/* 确保滚动条始终显示 */
	display: block !important;
}

.report-main::-webkit-scrollbar-track {
	background: #f1f1f1;
	border-radius: 4px;
	/* 确保轨道始终可见 */
	display: block !important;
}

.report-main::-webkit-scrollbar-thumb {
	background: var(--theme-primary);
	border-radius: 4px;
	/* 确保滑块始终可见 */
	display: block !important;
	min-height: 20px;
}

.report-main::-webkit-scrollbar-thumb:hover {
	background: var(--theme-primary-hover);
}

/* 缩放时的特殊处理 */
.report-main.scaled {
	/* 缩放时确保滚动条更明显 */
	overflow: auto !important;
	/* 确保内容可以正确滚动 */
	position: relative;
	/* 确保滚动条在最前面 */
	z-index: 1;
}

.report-main.scaled::-webkit-scrollbar {
	width: 16px;
	height: 16px;
	background: rgba(255, 255, 255, 0.9);
	/* 确保滚动条始终显示 */
	display: block !important;
}

.report-main.scaled::-webkit-scrollbar-track {
	background: rgba(241, 241, 241, 0.9);
	border-radius: 8px;
	border: 1px solid rgba(0, 0, 0, 0.1);
	/* 确保轨道始终可见 */
	display: block !important;
}

.report-main.scaled::-webkit-scrollbar-thumb {
	background: var(--theme-primary);
	border: 2px solid rgba(255, 255, 255, 0.9);
	border-radius: 8px;
	min-height: 30px;
	/* 确保滑块始终可见 */
	display: block !important;
	/* 添加阴影效果 */
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.report-main.scaled::-webkit-scrollbar-thumb:hover {
	background: var(--theme-primary-hover);
	box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}

.report-main.scaled::-webkit-scrollbar-corner {
	background: rgba(255, 255, 255, 0.9);
}

.report-title {
	text-align: center;
	font-size: 22px;
	font-weight: bold;
	color: #2176b8;
	margin: 0px 0 10px 0;
	letter-spacing: 2px;
}

.block {
	margin: 0 32px 18px 32px;
	background: #fff;
	border-radius: 8px;
	/* border: 1.2px solid #b5d2e8; */
	box-sizing: border-box;
	padding-bottom: 8px;
}

.block-title {
	background: var(--theme-primary);
	color: #fff;
	font-size: 16px;
	font-weight: 500;
	border-radius: 8px 8px 0 0;
	padding: 6px 18px;
	letter-spacing: 1px;
	text-align: left;
}

.info-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0 0;
	padding: 4px 18px 0 18px;
	text-align: left;
}

.info-item,
.info-item.fix-width,
.info-item.id-row {
	justify-content: flex-start;
	text-align: left;
	margin-top: 10px;
}

.fix-width-100 {
	width: 100%;
}

.fix-width-30 {
	width: 30%;
}

.info-item.fix-width {
	width: 50%;
	min-width: 120px;
	max-width: 350px;
	box-sizing: border-box;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	margin-bottom: 1px;
	padding-right: 8px;
	display: flex;
	align-items: center;
}

.info-item.id-row {
	width: 100%;
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	margin-bottom: 8px;
}


.input.id-input {
	width: 350px;
	max-width: 80%;

}

.label {
	color: #2176b8;
	font-weight: 500;
	margin-right: 2px;
}

.input {
	padding-bottom: 2px;
	border-bottom: 1px solid #999 !important;
	border: none;
	background: transparent;
	color: #222;
	font-size: 15px;
	outline: none;
	width: 60px;
}

.input.long {
	width: 260px;
}

.radio {
	font-size: 16px;
	color: #2176b8;
	margin: 0 2px;
}

.radio.checked {
	color: #2176b8;
}

.chart-area {
	padding: 12px 0 0 0;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.echart-box {
	width: 100%;
	height: 400px;
	background: #fff;
	border-radius: 8px;
	border: 1px solid #e0eaf3;
	margin-bottom: 0;
}

.heatmap-container {
	display: flex;
	flex-direction: column;
	align-items: center;
	margin: 20px 0;
}

.chart-title {
	font-size: 16px;
	font-weight: 500;
	color: #2176b8;
	margin-bottom: 10px;
	text-align: center;
}

.heatmap-title {
	font-size: 16px;
	font-weight: 500;
	color: #2176b8;
	margin-bottom: 10px;
	text-align: center;
}

.echart-box.heatmap {
	width: 50%;
	height: 200px;
	background: #fff;
}

.align-top {
	align-items: flex-start;
}

.opinion-box {
	flex: 2;
	display: flex;
	align-items: flex-start;
}

.opinion-input {
	flex: 1;
	padding: 5px;
	border: 1.2px solid #b5d2e8;
	border-radius: 6px;
	padding: 6px 10px;
	font-size: 12px;
	resize: none;
	background: #fafdff;
	margin-left: 4px;
	min-width: 220px;
	min-height: 48px;
}

.sign-box {
	flex: 1;
	display: flex;
	align-items: center;
	margin-left: 18px;
}

.sign-input {
	flex: 1;
	border: 1.2px solid #b5d2e8;
	border-radius: 6px;
	padding: 6px 10px;
	font-size: 15px;
	background: #fafdff;
	margin-left: 4px;
	min-width: 80px;
}

.submit-btn {
	background: #2176b8;
	color: #fff;
	border: none;
	border-radius: 8px;
	padding: 8px 28px;
	font-size: 16px;
	font-weight: 500;
	cursor: pointer;
	margin-left: 18px;
	margin-top: 8px;
	transition: background 0.2s;
}

.submit-btn:hover {
	background: #158ac0;
}

.right-btns {
	position: fixed;
	right: 48px;
	bottom: 48px;
	display: flex;
	flex-direction: column;
	gap: 18px;
	z-index: 10;
}

.right-btn {
	width: 90px;
	height: 38px;
	background: #fff;
	color: var(--theme-primary);
	border: 1.5px solid var(--theme-secondary);
	border-radius: 18px;
	font-size: 16px;
	font-weight: 500;
	cursor: pointer;
	box-shadow: 0 2px 8px rgba(30, 94, 146, 0.08);
	transition: background 0.2s, color 0.2s;
}

.right-btn:hover {
	background: var(--theme-primary);
	color: #fff;
}

.zoom-float-bar {
	position: fixed;
	right: 58px;
	bottom: 220px;
	z-index: 20;
	display: flex;
	align-items: center;
	gap: 8px;
	background: #fff;
	border-radius: 18px;
	box-shadow: 0 2px 8px rgba(30, 94, 146, 0.08);
	padding: 6px 18px;
	font-size: 14px;
}

.zoom-label,
.zoom-value {
	color: #2176b8;
}

.table-container {
	transition: transform 0.2s;
	/* 这里放表格的样式 */
}

.report-content {
	width: 100%;
	/* 确保缩放时内容能够正确显示 */
	min-height: 100%;
	position: relative;
}

.input-area {
	margin-bottom: 12px;
}

.input-label {
	color: #222;
	font-size: 15px;
	margin-bottom: 6px;
}

.input-row {
	display: flex;
	align-items: center;
	gap: 12px;
}

.input-content {
	flex: 1;
	min-height: 48px;
	border: 1.5px solid #b5d2e8;
	border-radius: 10px;
	font-size: 16px;
	padding: 8px 12px;
	resize: none;
	background: #fff;
}

.add-btn {
	width: 38px;
	height: 38px;
	border-radius: 50%;
	background: #2176b8;
	color: #fff;
	font-size: 28px;
	border: none;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background 0.2s;
}

.add-btn:hover {
	background: #158ac0;
}

.custom-table {
	border-collapse: collapse;
	width: 90%;
	margin-left: 5%;
}

.custom-table th,
.custom-table td {
	border: 1px solid #000;
	text-align: left;
	color: #333;
	height: 30px;
	font-size: 13px;
	height: 22px;
}

.custom-table th {
	background: #f5f8fa;
	color: #000;
}

.circle-btn {
	width: 36px;
	height: 36px;
	border-radius: 50%;
	border: none;
	margin-right: 8px;
	background: #eaf4fa;
	color: #2176b8;
	font-size: 20px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: background 0.2s, color 0.2s;
}

.circle-btn:last-child {
	margin-right: 0;
}

.circle-btn.checked {
	background: #2176b8;
	color: #fff;
}

.circle-btn.edit {
	background: #eaf4fa;
	color: #2176b8;
}

.circle-btn.delete {
	background: #eaf4fa;
	color: #d32f2f;
}

.circle-btn:hover {
	background: #158ac0;
	color: #fff;
}

.def-input-row {
	display: flex;
	margin-bottom: 12px;
}

.def-input-col {
	flex: 1;
	display: flex;
	flex-direction: column;
}

.def-input-label {
	color: #222;
	font-size: 15px;
	margin-bottom: 6px;
}

.def-input-textarea {
	width: 92%;
	min-height: 48px;
	border: 1.5px solid #b5d2e8;
	border-radius: 12px;
	font-size: 16px;
	padding: 10px 14px;
	resize: none;
	background: #fff;
	margin-bottom: 0;
}

.def-add-btn {
	margin-top: 20px;
	background: none;
	border: none;
	padding: 0;
	cursor: pointer;
	outline: none;
	display: flex;
	align-items: center;
	justify-content: center;
}

.def-table {
	width: 100%;
	border-collapse: separate;
	border-spacing: 0;
	margin-top: 10px;
	font-size: 16px;
	table-layout: fixed;
}

.def-table thead {
	display: table;
	width: 100%;
}

.def-table tbody {
	display: block;
	max-height: 300px;
	overflow-y: auto;
	scrollbar-width: thin;
	scrollbar-color: #2176b8 #e0eaf3;
}

.def-table tbody::-webkit-scrollbar {
	width: 6px;
}

.def-table tbody::-webkit-scrollbar-track {
	background: #e0eaf3;
}

.def-table tbody::-webkit-scrollbar-thumb {
	background-color: #2176b8;
	border-radius: 3px;
}

.def-table th {
	background: #2176b8;
	color: #fff;
	font-weight: 500;
	padding: 10px 0;

}

.def-table th,
.def-table td {
	text-align: left;
	padding: 10px 12px;
}

.def-table td {
	background: #fff;
	color: #222;
	border-bottom: 1px solid #e0eaf3;
	vertical-align: middle;
}

.def-td-serial {
	text-align: center;
	font-size: 16px;
	color: #2176b8;
	font-weight: 500;
}

.def-td-content {
	width: 500px;
	font-size: 16px;
	color: #222;
	word-break: break-all;
}

.def-td-actions {
	display: flex;
	align-items: center;
	gap: 16px;
	justify-content: center;
}

.def-circle-btn {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	border: none;
	background: none;
	padding: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: background 0.2s;
	background-color: #2176b8;
	color: #fff;
}

.def-circle-btn svg {
	display: block;
}

.def-circle-btn:hover {
	background: #eaf4fa;
}

.edit-input {
	width: 100%;
	padding: 5px;
	border: 1px solid #b5d2e8;
	border-radius: 4px;
	font-size: 14px;
}

.audio-controls {
	display: flex;
	align-items: center;
	justify-content: center;
}

.audio-btn {
	width: 32px;
	height: 32px;
	/* border-radius: 50%; */
	border: none;
	background: #2176b8;
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: background 0.2s;
	font-size: 20px;
	border-radius: 2px;
}

.audio-btn:hover:not(:disabled) {
	background: #158ac0;
}

.audio-btn:disabled {
	background: #ccc;
	cursor: not-allowed;
}

.images {
	display: flex;
	flex-wrap: wrap;
	gap: 20px;
	padding: 20px;
}

.image-item {
	display: flex;
	flex-direction: column;
	align-items: center;
	border: 1px solid #e0e0e0;
	border-radius: 8px;
	padding: 10px;
	background: #fff;
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.image-name {
	font-size: 14px;
	font-weight: 500;
	color: #2176b8;
	margin-bottom: 8px;
	text-align: center;
}

.canvas-image {
	max-width: 40vw;
	max-height: 40vh;
	border: 1px solid #ddd;
	border-radius: 4px;
	object-fit: contain;
}

.remark-content {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 5px;
}

.canvas-name {
	font-size: 12px;
	color: #333;
	font-weight: 500;
}
.dialog-btn {
  display: flex;
  justify-content: center;
  gap: 24px;
  margin-top: 32px;
}
.dialog-confirm {
  min-width: 90px;
  background: #5cc2e6;
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 18px;
  padding: 8px 0;
  cursor: pointer;
  transition: background 0.2s;
}
.dialog-confirm:hover {
  background: #1e5e92;
}
.dialog-cancel {
  min-width: 90px;
  background: #f3f3f3;
  color: #888;
  border: none;
  border-radius: 8px;
  font-size: 18px;
  padding: 8px 0;
  cursor: pointer;
  transition: background 0.2s;
}
.dialog-cancel:hover {
  background: #e0e0e0;
}

/* 滚动条指示器 */
.scroll-indicator {
	position: absolute;
	top: 10px;
	right: 10px;
	background: linear-gradient(135deg, var(--theme-primary), var(--theme-secondary));
	color: white;
	padding: 6px 12px;
	border-radius: 20px;
	font-size: 12px;
	z-index: 10;
	pointer-events: none;
	animation: fadeInOut 3s ease-in-out infinite;
	box-shadow: 0 2px 8px rgba(33, 118, 184, 0.3);
	border: 1px solid rgba(255, 255, 255, 0.2);
}

.scroll-indicator-text {
	font-weight: 500;
	white-space: nowrap;
}

@keyframes fadeInOut {
	0%, 100% { opacity: 0.8; transform: scale(1); }
	50% { opacity: 1; transform: scale(1.05); }
}

/* 签名输入框样式优化 */
.signature-input {
	background: transparent !important;
	outline: none !important;
	transition: all 0.3s ease;
	min-width: 200px;
	letter-spacing: 1px;
}

.signature-input:focus {
	border-bottom: 3px solid #2176b8 !important;
	box-shadow: 0 2px 4px rgba(33, 118, 184, 0.2);
}

.signature-input::placeholder {
	color: #999;
	font-style: italic;
}

/* 确保签名在保存图片时清晰可见 */
body.pdf-exporting .signature-input {
	border-bottom: 2px solid #2176b8 !important;
	background: transparent !important;
	color: #000 !important;
	font-weight: 600 !important;
	-webkit-print-color-adjust: exact !important;
	color-adjust: exact !important;
}

@media print {
	.signature-input {
		border-bottom: 2px solid #2176b8 !important;
		background: transparent !important;
		color: #000 !important;
		font-weight: 600 !important;
		-webkit-print-color-adjust: exact !important;
		color-adjust: exact !important;
	}
}
</style>
